12

我正在尝试使用 shutil.copytree:

shutil.copytree(SOURCE_DIR, TARGET_DIR, ignore=None)

此副本也是文​​件夹中的文件。我只需要复制没有任何文件的文件夹。怎么做?

4

6 回答 6

18

您可以通过提供“忽略”功能来做到这一点

def ig_f(dir, files):
    return [f for f in files if os.path.isfile(os.path.join(dir, f))]

shutil.copytree(SRC, DES, ignore=ig_f)

基本上,当您调用copytree时,它​​会递归地转到每个子文件夹并将该文件夹中的文件列表提供给忽略函数,以根据模式检查这些文件是否合适。忽略的文件将在函数末尾作为列表返回,然后,copytree 将仅复制该列表中不包括的项目(在您的情况下,包含当前文件夹中的所有文件)

于 2013-03-27T16:35:55.473 回答
2

这是@Oz123 解决方案的一个实现,它基于os.walk()

import os

def create_empty_dirtree(srcdir, dstdir, onerror=None):
    srcdir = os.path.abspath(srcdir)
    srcdir_prefix = len(srcdir) + len(os.path.sep)
    os.makedirs(dstdir)
    for root, dirs, files in os.walk(srcdir, onerror=onerror):
        for dirname in dirs:
            dirpath = os.path.join(dstdir, root[srcdir_prefix:], dirname)
            try:
                os.mkdir(dirpath)
            except OSError as e:
                if onerror is not None:
                    onerror(e)
于 2013-03-27T17:30:48.637 回答
1

您应该考虑使用os.walk.

这是 os.walk 的示例。这样您就可以列出所有目录,然后使用os.mkdir.

于 2013-03-27T16:18:00.610 回答
1

用于distutils.dir_util.create_tree仅复制目录结构(不是文件)

注意:参数files是文件名列表。如果你想要一些可以作为 shutils.copytree 工作的东西:

import os
import distutils.dir_util
def copy_tree(source, dest, **kwargs):
    filenames = [os.path.join(path, file_) for path, _, files in os.walk(source) for file_ in files]
    distutils.dir_util.create_tree(dest, filenames, **kwargs)
于 2013-03-27T16:40:16.050 回答
1

如果你想用 忽略模式功能os.walk(),那么:

ignorePatterns=[".git"]
def create_empty_dirtree(src, dest, onerror=None):
    src = os.path.abspath(src)
    src_prefix = len(src) + len(os.path.sep)
    for root, dirs, files in os.walk(src, onerror=onerror):
        for pattern in ignorePatterns:
            if pattern in root:
                break
        else:
            #If the above break didn't work, this part will be executed
            for dirname in dirs:
                for pattern in ignorePatterns:
                    if pattern in dirname:
                        break
                else:
                    #If the above break didn't work, this part will be executed
                    dirpath = os.path.join(dest, root[src_prefix:], dirname)
                    try:
                        os.makedirs(dirpath,exist_ok=True)
                    except OSError as e:
                        if onerror is not None:
                            onerror(e)
                continue #If the above else didn't executed, this will be reached

        continue #If the above else didn't executed, this will be reached

这将忽略.git目录。

注意:这需要Python >=3.2,因为我使用了旧版本不可用的exist_ok选项。makedirs

于 2015-05-11T18:19:59.537 回答
0

上述答案有效,但它们肯定不会无忧无虑,并且很容易花费您 30 分钟。如果您使用的是 Windows,最快的方法是打开 shell 并使用 xcopy,即:

c:\user> xcopy "source" "destination" /t /e

或者,如果你运行 Linux,你可以使用

rsync -a -f"+ */" -f"- *" source/ destination/
于 2021-08-14T12:59:20.830 回答