我想将具有相同结构的多个目录(子目录具有相同的名称)但不同的内容复制到第三个位置并合并它们。同时,我想忽略某些文件扩展名而不是复制它们。
我发现copy_tree()
库中的distutils.dir_util
函数可以轻松处理第一个任务。这里的问题是copy_tree()
不能忽略文件;它只是复制一切..
distutils.dir_util.copy_tree() - 示例
dirs_to_copy = [r'J:\Data\Folder_A', r'J:\Data\Folder_B']
destination_dir = r'J:\Data\DestinationFolder'
for files in dirs_to_copy:
distutils.dir_util.copy_tree(files, destination_dir)
# succeeds in merging sub-directories but copies everything.
# Due to time constrains, this is not an option.
对于第二项任务(使用“排除文件”选项进行复制),这次copytree()
库中存在shutil
函数。现在的问题是它无法合并文件夹,因为目标目录不能存在..
shutil.copytree() - 示例
dirs_to_copy = [r'J:\Data\Folder_A', r'J:\Data\Folder_B']
destination_dir = r'J:\Data\DestinationFolder'
for files in dirs_to_copy:
shutil.copytree(files, destination_dir, ignore=shutil.ignore_patterns("*.abc"))
# successfully ignores files with "abc" extensions but fails
# at the second iteration since "Destination" folder exists..
有什么能提供两全其美的东西,还是我必须自己编码呢?
答案 0 :(得分:3)
正如 PeterBrittain 建议的那样,编写我自己的shutil.copytree()
版本是可行的方法。下面是代码。请注意,唯一的区别是在os.makedirs()
块中包裹if
。
from shutil import copy2, copystat, Error, ignore_patterns
import os
def copytree_multi(src, dst, symlinks=False, ignore=None):
names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
# -------- E D I T --------
# os.path.isdir(dst)
if not os.path.isdir(dst):
os.makedirs(dst)
# -------- E D I T --------
errors = []
for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree_multi(srcname, dstname, symlinks, ignore)
else:
copy2(srcname, dstname)
except (IOError, os.error) as why:
errors.append((srcname, dstname, str(why)))
except Error as err:
errors.extend(err.args[0])
try:
copystat(src, dst)
except WindowsError:
pass
except OSError as why:
errors.extend((src, dst, str(why)))
if errors:
raise Error(errors)
答案 1 :(得分:0)
如果你想直接使用shutil,这是os.makedirs的一个热补丁,可以跳过错误。
import os
os_makedirs = os.makedirs
def safe_makedirs(name, mode=0777):
if not os.path.exists(name):
os_makedirs(name, mode)
os.makedirs = safe_makedirs
import shutil
dirs_to_copy = [r'J:\Data\Folder_A', r'J:\Data\Folder_B']
destination_dir = r'J:\Data\DestinationFolder'
if os.path.exists(destination_dir):
shutil.rmtree(destination_dir)
for files in dirs_to_copy:
shutil.copytree(files, destination_dir, ignore=shutil.ignore_patterns("*.abc")) code here