将文件复制到目录中,同时附加其原始的前导目录

3

我想知道Python是否提供了一种规范的方式将文件复制到目录中,并附加其原始前导目录,就像cp --parents所做的那样。 参考cp手册:

`--parents'
[...]
     cp --parents a/b/c existing_dir

 copies the file `a/b/c' to `existing_dir/a/b/c', creating any
 missing intermediate directories.

我在shutil的文档中没有看到与此相关的内容。当然,我可以在将任何文件复制到现有目录existing_dir之前,在该目录中创建整个目录结构,但这可能是额外的开销。


我认为这是你自己编程或找到一个具有此功能的库的类型。它依赖于相对路径,而shutil上的东西则不应如此。 - JBernardo
看一下 'os' 的文档 - 你想要模拟一个 'mkdir -p' 的路径,然后将文件复制到其中吗? - Jonathan Vanasco
@JonathanVanasco:是的,就是这样。 - michaelmeyer
4个回答

2

我最终想出了以下代码。它的作用几乎与cp --parents完全一样。

import os, shutil

def cp_parents(target_dir, files):
    dirs = []
    for file in files:
        dirs.append(os.path.dirname(file))
    dirs.sort(reverse=True)
    for i in range(len(dirs)):
        if not dirs[i] in dirs[i-1]:
            need_dir = os.path.normpath(target_dir + dirs[i])
            print("Creating", need_dir )
            os.makedirs(need_dir)
    for file in files:
        dest = os.path.normpath(target_dir + file)
        print("Copying %s to %s" % (file, dest))
        shutil.copy(file, dest)

这样调用:

target_dir = '/tmp/dummy'
files = [ '/tmp/dir/file1', '/tmp/dir/subdir/file2', '/tmp/file3' ]

cp_parents(target_dir, files)

输出结果为:

Creating /tmp/dummy/tmp/dir/subdir
Copying /tmp/dir/file1 to /tmp/dummy/tmp/dir/file1
Copying /tmp/dir/subdir/file2 to /tmp/dummy/tmp/dir/subdir/file2
Copying /tmp/file3 to /tmp/dummy/tmp/file3

也许有更好的处理方式,但这种方法可行。

0

仅支持3.6或更高版本(它使用f函数)

这是我实现的cp --parents

首先获取获取源目录和文件名的偏移量,以及目录偏移量(有时我想省略src文件的第一个文件夹)

然后提取文件夹和文件名(在src_dirs中进行检查是因为我注意到当src文件没有嵌套在任何文件夹中时会崩溃)

最后创建目标文件夹的目录树并将文件复制到其中

def __copy_parents(src, dest_folder, dir_offset=0):
    ''' Copies src tree into dest, offset (optional) omits n folders of the src path'''
    prev_offset = 0 if dir_offset == 0 else src.replace('/', '%', dir_offset - 1).find('/') + 1
    post_offset = src.rfind('/')

    src_dirs = '' if post_offset == -1 else src[prev_offset:post_offset]
    src_filename = src[post_offset + 1:]

    os.makedirs(f'{dest_folder}/{src_dirs}', exist_ok=True)
    shutil.copy(src, f'{dest_folder}/{src_dirs}/{src_filename}')

0

不确定您的具体要求,但听起来shutil.copytree适合您。您可以在这里看到完整的文档,但基本上您只需要在示例中调用类似以下的内容:

shutil.copytree( 'a/b/c', 'existing_dir/a/b/c' )

事实上,shutil.copytree会复制整个源目录树,而我想要的是只复制其中的一些文件。 - michaelmeyer
哦,我以为它只是从你指定的目录及其子目录中复制文件。编辑:重新阅读后发现我误解了 "c" 为我的答案中的一个目录,没有意识到你要它作为一个文件。 - max k.

0
import os
import shutil

files = [ '/usr/bin/ls','/etc/passwd' , '/var/log/daily.out' , '/var/log/system.log' , '/var/log/asl/StoreData' ]

def copy_structure(dst_dir,source_files):
    if not os.path.exists(dst_dir) and os.path.isdir(dst_dir):
        os.mkdir(dst_dir)
    for file in source_files:
        dir_name = os.path.dirname(file)
        final_dir_path = os.path.normpath(dst_dir+dir_name)
        if not os.path.exists(final_dir_path):
            os.makedirs(final_dir_path)            
        if os.path.exists(file): 
            shutil.copy(file,final_dir_path)

copy_structure('/tmp/backup',files)  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接