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

Copy file or directories recursively in Python

python似乎有复制文件的功能(如shutil.copy)和复制目录的功能(如shutil.copytree),但我没有找到同时处理这两者的功能。当然,检查您是想复制一个文件还是一个目录是很简单的,但这似乎是一个奇怪的遗漏。

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


我建议您首先调用shutil.copytree,如果抛出异常,则使用shutil.copy重试。

1
2
3
4
5
6
7
8
9
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


要添加Tzot和GNS答案,这里有一种递归复制文件和文件夹的替代方法。(Python 3。x)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)

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


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

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

所以你说的与cp -r类似的是shutil.copytree,因为cp -r针对并复制一个文件夹及其文件/子文件夹,如shutil.copytree。没有-rcp拷贝文件,如shutil.copyshutil.copy2做。


unix cp不支持目录和文件:

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

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

这里有一些断开连接,但是当传递一个文件名时-cp -r,因为源文件很乐意只复制单个文件;copytree不会。


我想你要找的是复制树


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
"
% 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('..')