使用Python将目录内容复制到另一个目录中

131
我有一个目录 /a/b/c,其中包含文件和子目录。 我需要将 /a/b/c/* 复制到 /x/y/z 目录中。我可以使用哪些 Python 方法?
我尝试过 shutil.copytree("a/b/c", "/x/y/z"),但是 Python 会尝试创建 /x/y/z 并引发 "目录已存在" 错误。

1
你是想移动还是复制目录?你的标题说是移动,但内容却说是复制。由于这两个操作是不同的,所以确切地知道你想要哪一个很重要。 - Carlos
1
Np。 正如@Xymostech所说,我们对期望的输出有些不清楚。 你想要:/x/y/z/a/b/c 还是 /x/y/z/c? 你使用copytree暗示了前者,但我只是想确认一下。 - Carlos
1
你能否先简单地删除任何 /x/y/z/ 目录 (shutil.rmtree()),然后再执行 copytree() - Eric O. Lebigot
@prosseek:您需要在所有深度上都这样做吗?例如,如果您有/a/b/c/t/u,您是否需要保留任何/x/y/z/t/v?也就是说,您只需要创建/覆盖,而不删除任何内容吗? - Eric O. Lebigot
4
自Python 3.8起,通过copytree函数的dirs_exist_ok=True参数,该问题已不再存在。详情请参见文档 - Jay
显示剩余4条评论
4个回答

229

1
一个很好的解决方案,我建议如果你需要的话,在copy_tree()中添加update=1 - Hai Vu
13
请注意,如果您对相同的参数调用copy_tree两次并在此期间清空了目标文件夹,则copy_tree将失败。这是由于mkpath中的路径缓存导致的,请参见https://bugs.python.org/issue10948。 - yacoob
1
有趣的是,在循环中使用shutil.copy2比整个复制目录要快得多。 - ikamen
7
如果你反复将文件夹复制到同一目标位置,请勿使用此功能。就像@yacoob所说,这样做会以出乎意料的方式失败。弄清楚这个问题让我头痛不已。我再次发表评论是为了增加其他人的注意。 - Martin Melka
3
FYI,pathlib的Path对象会破坏dir_utils,因为dir_utils需要以文本形式表示路径。 - knowingpark
显示剩余6条评论

4

1
from subprocess import call

def cp_dir(source, target):
    call(['cp', '-a', source, target]) # Linux

cp_dir('/a/b/c/', '/x/y/z/')

对我来说它有效。 基本上,它执行shell命令cp


9
好的,但这不是Pythonic的方式 :) - Artsiom Praneuski
@ArtsiomPraneuski 我同意,但有时可能会有帮助。 :) - Bowen Xu
3
除了 POSIX,不起作用。 - user707779
谢谢!这比其他方法快多了! - Alldb
@Alldb 它更快吗?你进行过基准测试吗? - user202729

-15

使用这个函数已经过时了,Python的库也不再需要了。我写了一个能正常工作的替代品:

import os
import shutil

def copydirectorykut(src, dst):
    os.chdir(dst)
    list=os.listdir(src)
    nom= src+'.txt'
    fitx= open(nom, 'w')

    for item in list:
        fitx.write("%s\n" % item)

    fitx.close()

    f = open(nom,'r')
    for line in f.readlines():
        if "." in line:
            shutil.copy(src+'/'+line[:-1],dst+'/'+line[:-1])
        else:
            if not os.path.exists(dst+'/'+line[:-1]):
                os.makedirs(dst+'/'+line[:-1])
                copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
            copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
    f.close()
    os.remove(nom)
    os.chdir('..')

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