复制和合并目录,不包括某些扩展名

Ev.*_*nis 11 python windows copy-paste

我想复制具有相同结构的多个目录(子目录具有相同的名称)但将不同的内容复制到第三个位置并合并它们.同时,我想忽略某些文件扩展名而不是复制它们.


我发现单独的第一个任务可以通过库中的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.
Run Code Online (Sandbox Code Playgroud)

对于第二个任务(使用"排除文件"选项进行复制),这次有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..
Run Code Online (Sandbox Code Playgroud)

有什么能提供两全其美的东西,还是我必须自己编码?

Ev.*_*nis 5

正如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)
Run Code Online (Sandbox Code Playgroud)