Python - moving and overwriting files and folders

I have a "Dst Directory" directory in which there are files and folders, and I have a "src Directory" in which there are also files and folders. What I want to do is move the contents of "src Directory" to "Dst Directory" and overwrite anyfiles that exist with the same name. So, for example, "Src Directory \ file.txt" must be moved to the "Dst Directory" and overwrite the existing .txt file. The same applies to some folders, moving a folder, and merging contents with the same folder in the dst directory

I am currently using shutil.move to move the contents of src to dst, but it will not work if the files already exist and will not merge the folders; it will just put the folder in the existing folder.

Update: make things a little clearer; What I am doing is unzipping the archive into the Dst directory, and then moving the contents of the Src directory and unpacking, effectively updating the files in the zip archive. This will be repeated to add new files or new versions of files, etc. Therefore it is necessary to overwrite and merge

Solved: I solved the problem using distutils.dir_util.copy_tree (src, dst), this copies the folders and files from the src directory to the dst directory and overwrites / merges where necessary. Hope this helps some people!

Hope this makes sense, thanks!

+49
python overwrite file move
Sep 14 '11 at 16:23
source share
6 answers

Instead, use copy() , which is ready to overwrite destination files. If you want the first tree to disappear, just rmtree() it separately, as soon as you finish on it.

http://docs.python.org/library/shutil.html#shutil.copy

http://docs.python.org/library/shutil.html#shutil.rmtree

Update:

Make os.walk() over the source tree. For each directory, check if it exists on the destination side, and os.makedirs() if it is missing. For each file, just shutil.copy() and the file will be created or overwritten, depending on what is appropriate.

+34
Sep 14 2018-11-11T00:
source share

This will go through the source directory, create any directories that do not yet exist in the destination directory, and move the files from the source to the destination directory:

 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) 

Before replacing the corresponding source file, all previously existing files will be deleted (via os.remove ). Any files or directories that already exist at the destination, but not at the source, remain untouched.

+44
Sep 14 '11 at 17:41
source share

Since none of the above worked for me, so I wrote my own recursive function. Call copyTree (dir1, dir2) to combine directories. Running on multi-platform Linux and 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) 
+6
Oct 10 '14 at 3:00
source share

If you also need to overwrite read-only flag files, use this:

 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) 
+3
Apr 20 '17 at 19:00
source share

Take a look at os.remove to delete existing files.

+1
Sep 14 '11 at 16:37
source share

I had a similar problem. I wanted to move files and folder structures and overwrite existing files, but not delete anything that is in the destination folder structure.

I solved it with os.walk() , recursively calling my function and using shutil.move() in the files I wanted to overwrite, and folders that weren't there.

It works like shutil.move() , but given that existing files are only overwritten but not deleted.

 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) 
-one
Apr 20 '15 at 13:35
source share



All Articles