有没有办法可以使用绝对路径过滤目录?
shutil.copytree(directory,
target_dir,
ignore = shutil.ignore_patterns("/Full/Path/To/aDir/Common"))
尝试过滤位于“aDir
”下的“公共”目录时似乎不起作用。如果我这样做:
shutil.copytree(directory,
target_dir,
ignore = shutil.ignore_patterns("Common"))
它可以工作,但每个名为Common的目录都将在“树”中过滤,这不是我想要的。
有什么建议吗?
感谢。
答案 0 :(得分:13)
您可以创建自己的忽略功能:
shutil.copytree('/Full/Path', 'target',
ignore=lambda directory, contents: ['Common'] if directory == '/Full/Path/To/aDir' else [])
或者,如果您希望能够使用相对路径调用copytree
:
import os.path
def ignorePath(path):
def ignoref(directory, contents):
return (f for f in contents if os.abspath(os.path.join(directory, f)) == path)
return ignoref
shutil.copytree('Path', 'target', ignore=ignorePath('/Full/Path/To/aDir/Common'))
来自文档:
如果给出忽略,则它必须是可以作为其接收的可调用对象 参数copytree()访问的目录及其列表 内容,由os.listdir()返回。因为copytree()被调用 递归地,将为每个调用一次ignore callable 复制的目录。 callable必须返回一个序列 相对于当前目录的目录和文件名(即a 第二个参数中项目的子集);这些名字将是 在复制过程中被忽略。 ignore_patterns()可用于创建 这样一个可调用的,它根据glob样式模式忽略名称。
答案 1 :(得分:4)
shutil.ignore_patterns()的API不支持绝对路径,但滚动自己的变体非常容易。
作为起点,请查看* ignore_patterns *:
的源代码def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
您可以看到它返回一个接受路径和名称列表的函数,并返回一组要忽略的名称。要支持您的用例,请创建您自己的类似函数,该函数使用 path 参数。将您的函数传递给 copytree()的调用中的ignore参数。
或者,不要按原样使用 shutil 。源代码简短而且甜美,因此不难切割,粘贴和自定义。
答案 2 :(得分:3)
您需要创建自己的ignore函数,该函数检查当前正在处理的目录,并且仅当dir为'/ Full / Path / To / aDir'时才返回包含'Common'的列表。
def ignore_full_path_common(dir, files):
if dir == '/Full/Path/To/aDir':
return ['Common']
return []
shutil.copytree(directory, target_dir, ignore=ignore_full_path_common)
答案 3 :(得分:0)
非常感谢您的回答。它帮助我设计了我自己的 ignore_patterns()
函数以满足有点不同的需求。在这里粘贴代码,它可能对某人有所帮助。
下面是使用绝对路径排除多个文件/目录的 ignore_patterns()
函数。
myExclusionList
--> 包含复制时要排除的文件/目录的列表。此列表可以包含通配符模式。列表中的路径与提供的 srcpath
相关。例如:
[排除名单]
java/app/src/main/webapp/WEB-INF/lib/test
unittests
python-buildreqs/apps/abc.tar.gz
3rd-party/jdk*
代码粘贴在下面
def copydir(srcpath, dstpath, myExclusionList, log):
patternlist = []
try:
# Forming the absolute path of files/directories to be excluded
for pattern in myExclusionList:
tmpsrcpath = join(srcpath, pattern)
patternlist.extend(glob.glob(tmpsrcpath)) # myExclusionList can contain wildcard pattern hence glob is used
copytree(srcpath, dstpath, ignore=ignore_patterns_override(*patternlist))
except (IOError, os.error) as why:
log.warning("Unable to copy %s to %s because %s", srcpath, dstpath, str(why))
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error as err:
log.warning("Unable to copy %s to %s because %s", srcpath, dstpath, str(err))
# [START: Ignore Patterns]
# Modified Function to ignore patterns while copying.
# Default Python Implementation does not exclude absolute path
# given for files/directories
def ignore_patterns_override(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files/directories"""
def _ignore_patterns(path, names):
ignored_names = []
for f in names:
for pattern in patterns:
if os.path.abspath(join(path, f)) == pattern:
ignored_names.append(f)
return set(ignored_names)
return _ignore_patterns
# [END: Ignore Patterns]