如何使用 python 执行非递归复制
How to perform a non recursive copy using python
我需要复制具有特定模式的文件。我需要使用 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
每个模式并将结果连接在一起(在列表理解中):
import os, shutil, glob
src = 'my_dir'
dst = 'my_dir_cp'
try:
os.mkdir(dst)
except FileExistsError:
pass
patterns_to_ignore = ['*.txt', '*.bat']
ignore = [e for p in patterns_to_ignore for e in glob.glob(os.path.join(src, p))]
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)
这更像是一种 hack,但会以非递归方式将目录中的所有文件复制到目标目录。您可以使用 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)
# use copyfiles like so:
copyfiles(src_directory, dst_directory, ignore=shutil.ignore_patterns('*.txt')) # copies non-recursively
我需要复制具有特定模式的文件。我需要使用 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
每个模式并将结果连接在一起(在列表理解中):
import os, shutil, glob
src = 'my_dir'
dst = 'my_dir_cp'
try:
os.mkdir(dst)
except FileExistsError:
pass
patterns_to_ignore = ['*.txt', '*.bat']
ignore = [e for p in patterns_to_ignore for e in glob.glob(os.path.join(src, p))]
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)
这更像是一种 hack,但会以非递归方式将目录中的所有文件复制到目标目录。您可以使用 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)
# use copyfiles like so:
copyfiles(src_directory, dst_directory, ignore=shutil.ignore_patterns('*.txt')) # copies non-recursively