带有否定忽略模式的python copytree

时间:2010-05-12 18:44:52

标签: python regex

我正在尝试使用python来复制文件/目录树。

是否可以使用copytree复制以foo结尾的所有内容?

有一个ignore_patterns模式函数,我可以给它一个否定的正则表达式吗?它们是否支持python?

例如

copytree(src,dest,False,ignore_pattern('!*。foo')) 哪里!不是指以foo结尾的任何东西。 感谢。

4 个答案:

答案 0 :(得分:7)

shutil.copytree有一个ignore keywordignore可以设置为任何可调用的。给定被访问的目录及其内容列表,callable应返回一系列目录和文件名以供忽略。

例如:

import shutil
def ignored_files(adir,filenames):
    return [filename for filename in filenames if not filename.endswith('foo')]

shutil.copytree(source, destination, ignore=ignored_files)

答案 1 :(得分:4)

以unutbu的答案为基础。下面列出了所有文件,然后删除匹配的“ignore_patterns”,然后将其作为忽略的文件列表返回。也就是说,它只会复制你想要的文件。

import glob, os, shutil

def copyonly(dirpath, contents):
    return set(contents) - set(
        shutil.ignore_patterns('*.py', '*.el')(dirpath, contents),
        )

shutil.copytree(
    src='.',
    dst='temp/',
    ignore=copyonly,
    )
print glob.glob('temp/*')

答案 2 :(得分:0)

def documentation(format):
    call(['make', format, '-C', DOC_SOURCE_DIR])

    if (os.path.exists(DOC_DIR)):
        shutil.rmtree(DOC_DIR)

    ignored = ['doctrees']
    shutil.copytree('{0}/build/'.format(DOC_SOURCE_DIR), DOC_DIR, ignore=shutil.ignore_patterns(*ignored))

答案 3 :(得分:0)

此解决方案建立在@unutbu@johntellsall之上,还可以递归工作。

def inverse_ignore_patterns(*patterns: str):
    def _inverse_ignore_patterns(path, names):
        ignored_names = set(names)
        for pattern in patterns:
            ignored_names -= set(fnmatch.filter(names, pattern))

        # Keep folders
        ignored_names -= {
            name for name in ignored_names
            if os.path.isdir(os.path.join(path, name))
        }
        return ignored_names

    return _inverse_ignore_patterns

一个缺点是,如果目录中不包含任何匹配文件,则会创建空目录。您可以使用以下方法轻松解决此问题:

def rm_empty_folders(rootdir: str):
    for dirpath, dirnames, filenames in os.walk(rootdir, topdown=False):
        if not os.listdir(dirpath):
            os.rmdir(dirpath)

用作:

copytree(src, dest, False, inverse_ignore_patterns("*.foo"))
rm_empty_folders(dest)