如何使用python执行非递归复制

如何使用python执行非递归复制,python,copy,shutil,non-recursive,Python,Copy,Shutil,Non Recursive,我需要复制具有特定模式的文件。我需要使用shutil在给定目录上执行非递归复制。我用递归复制尝试了下面给出的代码。是否有任何选项可在其中指定以执行非递归复制 from fnmatch import fnmatch, filter from os.path import isdir, join from shutil import copytree, ignore_patterns src_directory = r'PATH' dst_directory

我需要复制具有特定模式的文件。我需要使用shutil在给定目录上执行非递归复制。我用递归复制尝试了下面给出的代码。是否有任何选项可在其中指定以执行非递归复制

    from fnmatch import fnmatch, filter
    from os.path import isdir, join
    from shutil import copytree, ignore_patterns

    src_directory = r'PATH'
    dst_directory = r'PATH'
    copytree(src_directory, ignored_directory,ignore=ignore_patterns('*.txt'))

首先确保目标目录存在。 然后使用
glob.glob
创建要忽略的所有文件的列表。然后迭代
src
目录中的所有文件和目录,并将每个文件复制到
dst
目录(如果它是文件且不在
ignore
列表中):

import os, shutil, glob
src = 'my_dir'
dst = 'my_dir_cp'

try:
    os.mkdir(dst)
except FileExistsError:
    pass

ignore = glob.glob(os.path.join(src, '*.txt'))
for file in os.listdir(src):
    file = os.path.join(src, file)
    if file not in ignore and os.path.isfile(file):
        shutil.copy(file, dst)

一个完整的例子:

$ ls my_dir
bob  cat.txt  fish  jim
$ python -q
>>> import os, shutil, glob
>>> src = 'my_dir'
>>> dst = 'my_dir_cp'
>>> 
>>> try:
...     os.mkdir(dst)
... except FileExistsError:
...     pass
... 
>>> ignore = glob.glob(os.path.join(src, '*.txt'))
>>> for file in os.listdir(src):
...     file = os.path.join(src, file)
...     if file not in ignore and os.path.isfile(file):
...         shutil.copy(file, dst)
... 
'my_dir_cp/jim'
'my_dir_cp/bob'
>>> 
$ ls my_dir_cp
bob  jim

如果您希望能够忽略多个
glob
模式,那么您可以
glob.glob
每个模式,并将结果连接在一起(在列表中):


这更像是一种黑客行为,但会以非递归方式将目录中的所有文件复制到目标目录。可以使用glob或regex忽略文件-

import re

def copytree(src, dst):
     for item in [f for f in os.listdir(src) if os.path.isfile(os.path.join(src, f)) if not re.match(f, '[.]txt$')]:
         s = os.path.join(src, item)
         d = os.path.join(dst, item)
         shutil.copy2(s, d)

当您选择从
shutil
使用
copytree
时,请注意,任何循环复制每个文件的解决方案都会遗漏
copytree
的许多优秀功能,例如符号链接处理、复制文件元数据等

通过创建一个名为
copyfiles
的非递归
copytree
,您可以保留所有额外内容
copyfiles
的工作原理与
copytree
相同,只是它扩展了
ignore
参数,以便在复制时也忽略文件夹

import shutil, os

def copyfiles(src, dst, ignore=lambda a, b: set(), **kwargs):
    return shutil.copytree(src, dst, ignore=lambda s, names: set(ignore(s, names)).union(set(filter(lambda name: os.path.isdir(os.path.join(s, name)), names))), **kwargs)

你说的非递归是什么意思?只有来自某个目录的文件,或者同时来自文件和目录,但这些目录下没有任何内容?只有来自某个目录的文件,而不是文件夹@thatbird任何解决方案的可能副本,在该解决方案中,您通过通配符复制文件,而忽略了copytree的许多优秀功能,例如符号链接处理、复制文件元数据、,etc.创建一个真正的copytreehow非递归版本,用ignore附加多个扩展名,例如*.bat、*txt和etc@JoeIddon@Jarvis好的,我会补充,但是请接受这个答案!
import shutil, os

def copyfiles(src, dst, ignore=lambda a, b: set(), **kwargs):
    return shutil.copytree(src, dst, ignore=lambda s, names: set(ignore(s, names)).union(set(filter(lambda name: os.path.isdir(os.path.join(s, name)), names))), **kwargs)
# use copyfiles like so:

copyfiles(src_directory, dst_directory, ignore=shutil.ignore_patterns('*.txt')) # copies non-recursively