Python – 移动并覆盖文件和文件夹
我有一个目录,“Dst目录”,其中有文件和文件夹,我有'src目录',其中也有文件和文件夹。 我想要做的是将'src目录'的内容移动到'Dst目录',并覆盖任何存在同名的文件。 因此,例如'Src Directory \ file.txt'需要移动到'Dst Directory'并覆盖现有的file.txt。 这同样适用于某些文件夹,移动一个文件夹并将内容与“dst目录”中的同一文件夹合并
我目前正在使用shutil.move将src的内容移到dst,但是如果这些文件已经存在并且不会合并文件夹, 它只会把文件夹放在现有的文件夹中。
更新:使事情更清楚一点; 我正在做的是将档案解压缩到Dst目录,然后将Src目录的内容移到那里并重新压缩,有效地更新zip档案中的文件。 这将重复添加新的文件或新版本的文件等,这就是为什么它需要覆盖和合并
解决:我解决了我的问题,通过使用distutils.dir_util.copy_tree(src,dst),这将从src目录中的文件夹和文件复制到dst目录,并覆盖/合并在哪里neccesary。 希望能帮助一些人!
希望有道理,谢谢!
使用copy()
代替,它愿意覆盖目标文件。 如果你想要第一棵树消失,只要rmtree()
它分开,一旦你完成了迭代。
http://docs.python.org/library/shutil.html#shutil.copy
http://docs.python.org/library/shutil.html#shutil.rmtree
更新:
在源代码树上执行os.walk()
。 对于每个目录,检查它是否存在于目标端,如果缺失则检查os.makedirs()
。 对于每个文件,只需shutil.copy()
和该文件将被创build或覆盖,无论哪个适当。
这将通过源目录,创build目标目录中不存在的任何目录,并将文件从源移动到目标目录:
import os import shutil root_src_dir = 'Src Directory\\' root_dst_dir = 'Dst Directory\\' 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.move(src_file, dst_dir)
任何预先存在的文件在被相应的源文件replace之前将首先被移除(通过os.remove
)。 已经存在于目的地但不在源中的任何文件或目录将保持不变。
由于以上都没有为我工作,所以我写了我自己的recursion函数。 调用函数copyTree(dir1,dir2)来合并目录。 在多平台Linux和Windows上运行。
def forceMergeFlatDir(srcDir, dstDir): if not os.path.exists(dstDir): os.makedirs(dstDir) for item in os.listdir(srcDir): srcFile = os.path.join(srcDir, item) dstFile = os.path.join(dstDir, item) forceCopyFile(srcFile, dstFile) def forceCopyFile (sfile, dfile): if os.path.isfile(sfile): shutil.copy2(sfile, dfile) def isAFlatDir(sDir): for item in os.listdir(sDir): sItem = os.path.join(sDir, item) if os.path.isdir(sItem): return False return True def copyTree(src, dst): for item in os.listdir(src): s = os.path.join(src, item) d = os.path.join(dst, item) if os.path.isfile(s): if not os.path.exists(dst): os.makedirs(dst) forceCopyFile(s,d) if os.path.isdir(s): isRecursive = not isAFlatDir(s) if isRecursive: copyTree(s, d) else: forceMergeFlatDir(s, d)
如果您还需要使用只读标志覆盖文件,请使用以下命令:
def copyDirTree(root_src_dir,root_dst_dir): """ Copy directory tree. Overwrites also read only files. :param root_src_dir: source directory :param root_dst_dir: destination directory """ 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): try: os.remove(dst_file) except PermissionError as exc: os.chmod(dst_file, stat.S_IWUSR) os.remove(dst_file) shutil.copy(src_file, dst_dir)
看看: os.remove
删除现有的文件。
我有一个类似的问题。 我想移动文件和文件夹结构并覆盖现有文件,但不删除目标文件夹结构中的任何内容。
我解决了这个问题,使用os.walk()
,recursion调用我的函数,并使用shutil.move()
我想覆盖文件和不存在的文件夹。
它的工作原理就像shutil.move()
,但是现有的文件只能被覆盖,而不shutil.move()
删除。
import os import shutil def moverecursively(source_folder, destination_folder): basename = os.path.basename(source_folder) dest_dir = os.path.join(destination_folder, basename) if not os.path.exists(dest_dir): shutil.move(source_folder, destination_folder) else: dst_path = os.path.join(destination_folder, basename) for root, dirs, files in os.walk(source_folder): for item in files: src_path = os.path.join(root, item) if os.path.exists(dst_file): os.remove(dst_file) shutil.move(src_path, dst_path) for item in dirs: src_path = os.path.join(root, item) moverecursively(src_path, dst_path)