The copy2() method in Python is used to copy the content of the source file to the destination file or directory. This method is identical to shutil. copy() method also preserving the file's metadata.
If you don't want to copy the whole tree (with subdirs etc), use or glob. glob("path/to/dir/*. *") to get a list of all the filenames, loop over the list and use shutil. copy to copy each file.
Here's a solution that's part of the standard library:
from distutils.dir_util import copy_tree
copy_tree("/a/b/c", "/x/y/z")
See this similar question.
Copy directory contents into a directory with python
This limitation of the standard shutil.copytree
seems arbitrary and annoying. Workaround:
import os, shutil
def copytree(src, dst, symlinks=False, ignore=None):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
shutil.copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
Note that it's not entirely consistent with the standard copytree
:
symlinks
and ignore
parameters for the root directory of the src
tree;shutil.Error
for errors at the root level of src
;shutil.Error
for that subtree instead of trying to copy other subtrees and raising single combined shutil.Error
.Python 3.8 introduced the dirs_exist_ok
argument to shutil.copytree
:
Recursively copy an entire directory tree rooted at src to a directory named dst and return the destination directory. dirs_exist_ok dictates whether to raise an exception in case dst or any missing parent directory already exists.
Therefore, with Python 3.8+ this should work:
import shutil
shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo', dirs_exist_ok=True)
In slight improvement on atzz's answer to the function where the above function always tries to copy the files from source to destination.
def copytree(src, dst, symlinks=False, ignore=None):
if not os.path.exists(dst):
os.makedirs(dst)
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
copytree(s, d, symlinks, ignore)
else:
if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
shutil.copy2(s, d)
In my above implementation
I am using above function along with scons build. It helped me a lot as every time when I compile I may not need to copy entire set of files.. but only the files which are modified.
A merge one inspired by atzz and Mital Vora:
#!/usr/bin/python
import os
import shutil
import stat
def copytree(src, dst, symlinks = False, ignore = None):
if not os.path.exists(dst):
os.makedirs(dst)
shutil.copystat(src, dst)
lst = os.listdir(src)
if ignore:
excl = ignore(src, lst)
lst = [x for x in lst if x not in excl]
for item in lst:
s = os.path.join(src, item)
d = os.path.join(dst, item)
if symlinks and os.path.islink(s):
if os.path.lexists(d):
os.remove(d)
os.symlink(os.readlink(s), d)
try:
st = os.lstat(s)
mode = stat.S_IMODE(st.st_mode)
os.lchmod(d, mode)
except:
pass # lchmod not available
elif os.path.isdir(s):
copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With