复制具有特定扩展名的所有文件,同时保留目录树

时间:2014-09-03 11:44:53

标签: python

我的问题

  1. 遍历目录,找到所有头文件*.h
  2. 将所有这些文件复制到另一个位置,但维护目录树
  3. 我尝试了什么

    我已经能够使用os

    收集所有标题
    for root, dirs, files in os.walk(r'D:\folder\build'):
        for f in files:
            if f.endswith('.h'):
                print os.path.join(root, f)
    

    这正确打印:

    D:\folder\build\a.h
    D:\folder\build\b.h
    D:\folder\build\subfolder\c.h
    D:\folder\build\subfolder\d.h
    

    我被困的地方

    使用完整文件路径列表,如何在维护子目录的同时将这些文件复制到另一个位置?在上面的示例中,我想将目录结构维护在\build\

    下面

    例如,我希望副本创建以下内容:

    D:\other\subfolder\build\a.h
    D:\other\subfolder\build\b.h
    D:\other\subfolder\build\subfolder\c.h
    D:\other\subfolder\build\subfolder\d.h
    

3 个答案:

答案 0 :(得分:6)

您可以使用shutil.copytree并使用忽略可调用来过滤要复制的文件。

"如果给出了ignore,它必须是一个可调用的,它将接收copytree()访问的目录作为其参数,以及它的内容列表(...)。 callable必须返回一系列相对于当前目录的目录和文件名(即第二个参数中的项的子集);然后在复制过程中忽略这些名称"

因此,根据您的具体情况,您可以写下:

from os.path import join, isfile
from shutil import copytree

# ignore any files but files with '.h' extension
ignore_func = lambda d, files: [f for f in files if isfile(join(d, f)) and f[-2:] != '.h']
copytree(src_dir, dest_dir, ignore=ignore_func)

答案 1 :(得分:2)

编辑:如@pchiquet所示,它可以在一个命令中完成。然而,我将展示如何手动解决这个问题。

你需要三件事。

您知道要遍历的目录,因此要构造目标路径,需要使用目标根目录的名称替换源根目录的名称:

walked_directory = 'D:\folder\build'
found_file = 'D:\other\subfolder\build\a.h'
destination_directory = 'D:\other\subfolder'
destination_file = found_file.replace('walked_directory', 'destination_directory')

既然您有源和目的地,首先需要确保目的地存在:

os.makedirs(os.path.dirname(destination_file))

一旦存在,您可以复制文件:

shutil.copyfile(found_file, destination_file)

答案 2 :(得分:0)

这将以递归方式将所有扩展名为'.h'的文件从当前目录复制到dest_dir,而无需在dest_dir中创建子目录:

import glob
import shutil
from pathlib import Path

# ignore any files but files with '.h' extension
for file in glob.glob('**/*.h', recursive=True):
    shutil.copyfile(
        Path(file).absolute(), 
        (Past(dest_dir)/Path(file).name).absolute()
    )