替换 python 中的多个文件和文件夹

Replace multiple files and folders in python

我该怎么做呢?我有一个包含很多子文件夹和文件的大文件夹,我想用存储在其他地方的包含相同文件结构的其他文件夹和文件替换多个特定的文件夹和文件。

BigFolder
|
|--Folder 1
|--Folder 2
|--Folder 3
|--Folder 4
|--File 1
|--File 2


"Backup 1"
|
|--Folder 1
|--Folder 3
|--File 2

"Backup 2"
|
|--Folder 1
|--Folder 3
|--File 2

"Backup 3"
|
|--Folder 1
|--Folder 3
|--File 2

我将“备份”放在引号中,因为这不是它的真正目的,但它可以作为示例。所以我应该能够抓取大文件夹的具体内容并将它们放入一个备份中,然后再进行另一个备份并抓取其内容并将它们放入大文件夹中,基本上是交换它们。我怎么能做到这一点?我尝试使用 shutil.copytree 但这会引发错误,因为我要复制到的文件夹已经存在,这真是愚蠢的限制。我也尝试过使用 distutils 的 copytree,但是虽然它可以工作,但它不会复制我想要的文件夹,只会复制内容,所以它不会保留文件结构。

import shutil

bigFolder = "/home/user/Big Folder"

def swapFiles(newFolder, prevFolder):
    path = os.path
    #Copy from big folder to the previous backup
    shutil.copytree(path.join(bigFolder, "Folder 1"), prevFolder)
    shutil.copytree(path.join(bigFolder, "Folder 3"), prevFolder)
    shutil.copy(path.join(bigFolder, "File 2"), prevFolder)

    #Copy from new folder to big folder
    shutil.copytree(newFolder, bigFolder)

这不起作用,因为它的目标文件夹已经存在,它只适用于不存在的文件夹。使用 distutils:

from distutils.dir_util import copy_tree
import shutil

bigFolder = "/home/user/Big Folder"

def swapFiles(newFolder, prevFolder):
    path = os.path
    #Copy from big folder to the previous backup
    copy_tree(path.join(bigFolder, "Folder 1"), prevFolder)
    copy_tree(path.join(bigFolder, "Folder 3"), prevFolder)
    shutil.copy(path.join(bigFolder, "File 2"), prevFolder) #shutil is fine here

    #Copy from new folder to big folder
    copy_tree(newFolder, bigFolder)

这不起作用,因为它复制文件夹的内容而不是文件夹本身,所以我不保留文件结构。

顺便说一句,在两个复制过程的中间,我应该删除文件和文件夹以避免与新文件夹的合并,但这与问题无关。

#recursively merge two folders including subfolders
def mergefolders(root_src_dir, root_dst_dir):
    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)

来源:https://lukelogbook.tech/2018/01/25/merging-two-folders-in-python/

我找到了一个解决方案,结果证明 shutil 只能将文件复制到不存在的文件夹的愚蠢限制毕竟是有用的,但我还需要使用 distutils 的 copy_tree 功能,幸运的是,它们都是标准库。首先,创建一个包含所有要复制的文件和文件夹的列表:

filesToCopy = ["File 2", "Folder 1", "Folder 3"]

然后我们需要为每个阶段创建几个循环。

import shutil, os
from distutils.dir_util import copy_tree

def swapFiles(newDir, prevDir):
    bigFolder = "Big Folder/Path"

    #Copy from the big folder to the prevDir
    for file in filesToCopy:
    #Check if what you're about to copy is a directory
    if os.path.isdir(os.path.join(bigFolder, file)):
        copy_tree(os.path.join(bigFolder, file), os.path.join(prevDir, file))
    else:
        #If its a file, do a simple copy
        shutil.copy(os.path.join(bigFolder, file), os.path.join(prevDir, file))

    #Remove the copies folders from the big folder
    for file in filesToCopy:
        if os.path.isdir(os.path.join(bigFolder, file)):
            shutil.rmtree(os.path.join(bigFolder, file))
        else:
            os.remove(os.path.join(bigFolder, file))

    #Copy over files from newDir to bigFolder
    for file in filesToCopy:
        if os.path.isdir(os.path.join(newDir, file)):
            #I use shutil's copytree here because I want it to create the folders I deleted in the previous step
            shutil.copytree(os.path.join(newDir, file), os.path.join(bigFolder, file))
        else:
            shutil.copy(os.path.join(newDir, file), os.path.join(bigFolder, file))

有了这个,文件结构得以保持,并且很容易指定要交换的文件和文件夹。