在Python中递归复制文件或目录

时间:2010-01-03 10:06:42

标签: python

Python似乎具有复制文件的功能(例如shutil.copy)和复制目录的功能(例如shutil.copytree),但我没有找到任何处理这两者的函数。当然,检查是否要复制文件或目录是微不足道的,但这似乎是一个奇怪的遗漏。

是否真的没有像unix cp -r命令那样工作的标准函数,即递归支持目录,文件和副本?在Python中解决这个问题最优雅的方法是什么?

6 个答案:

答案 0 :(得分:126)

我建议您先拨打shutil.copytree,如果抛出异常,请使用shutil.copy重试。

import shutil, errno

def copyanything(src, dst):
    try:
        shutil.copytree(src, dst)
    except OSError as exc: # python >2.5
        if exc.errno == errno.ENOTDIR:
            shutil.copy(src, dst)
        else: raise

答案 1 :(得分:3)

shutil.copyshutil.copy2正在复制文件。

shutil.copytree复制包含所有文件和所有子文件夹的文件夹。 shutil.copytree正在使用shutil.copy2复制文件。

因此,您所说的cp -r类似于shutil.copytree,因为cp -r定位并复制文件夹及其文件/子文件夹,如shutil.copytree。没有-r cp副本文件,例如shutil.copyshutil.copy2

答案 2 :(得分:3)

要添加Tzot'sgns个答案,这里是另一种递归复制文件和文件夹的方法。 (Python 3.X)

import os, shutil

root_src_dir = r'C:\MyMusic'    #Path/Location of the source directory
root_dst_dir = 'D:MusicBackUp'  #Path to the destination folder

for src_dir, dirs, files in os.walk(root_src_dir):
    dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    for file_ in files:
        src_file = os.path.join(src_dir, file_)
        dst_file = os.path.join(dst_dir, file_)
        if os.path.exists(dst_file):
            os.remove(dst_file)
        shutil.copy(src_file, dst_dir)

如果这是你的第一次并且你不知道如何递归地复制文件和文件夹,我希望这会有所帮助。

答案 3 :(得分:2)

Unix cp不支持“目录和文件”:

betelgeuse:tmp james$ cp source/ dest/
cp: source/ is a directory (not copied).

要使cp复制目录,您必须使用'-r'标志手动告诉cp它是一个目录。

虽然这里有一些脱节 - cp -r传递文件名时,因为源会很乐意复制单个文件; copytree不会。

答案 4 :(得分:0)

我认为copy_tree正是你要找的东西

答案 5 :(得分:-2)

python shutil.copytree方法一团糟。我做了一个正常工作:

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('..')