I'm trying use shutil.copytree:
shutil.copytree(SOURCE_DIR, TARGET_DIR, ignore=None)
This copy also files in folder. I need copy only folders without ANY files. How to do it?
I'm trying use shutil.copytree:
shutil.copytree(SOURCE_DIR, TARGET_DIR, ignore=None)
This copy also files in folder. I need copy only folders without ANY files. How to do it?
You can do that by providing a "ignore" function
def ig_f(dir, files):
return [f for f in files if os.path.isfile(os.path.join(dir, f))]
shutil.copytree(SRC, DES, ignore=ig_f)
Basically, when you call copytree, it will recursively go to each child folder and provide a list of files in that folder to the ignore function to check if those files are suitable based on a pattern. The ignored files will be returned as a list in the end of the function and then, copytree will only copy items excluding from that list (which in your case, contains all the files in the current folder)
Here's an implementation of @Oz123's solution which is based on os.walk()
:
import os
def create_empty_dirtree(srcdir, dstdir, onerror=None):
srcdir = os.path.abspath(srcdir)
srcdir_prefix = len(srcdir) + len(os.path.sep)
os.makedirs(dstdir)
for root, dirs, files in os.walk(srcdir, onerror=onerror):
for dirname in dirs:
dirpath = os.path.join(dstdir, root[srcdir_prefix:], dirname)
try:
os.mkdir(dirpath)
except OSError as e:
if onerror is not None:
onerror(e)
You should consider using os.walk
.
Here is an example for os.walk. This way you could list all the directories and then create them with os.mkdir
.
use distutils.dir_util.create_tree
to just copy directory structure (not files)
note : the argument files
is a list of filenames. if you want something that would work as shutils.copytree:
import os
import distutils.dir_util
def copy_tree(source, dest, **kwargs):
filenames = [os.path.join(path, file_) for path, _, files in os.walk(source) for file_ in files]
distutils.dir_util.create_tree(dest, filenames, **kwargs)
If you want ignore pattern functionality with os.walk()
, then:
ignorePatterns=[".git"]
def create_empty_dirtree(src, dest, onerror=None):
src = os.path.abspath(src)
src_prefix = len(src) + len(os.path.sep)
for root, dirs, files in os.walk(src, onerror=onerror):
for pattern in ignorePatterns:
if pattern in root:
break
else:
#If the above break didn't work, this part will be executed
for dirname in dirs:
for pattern in ignorePatterns:
if pattern in dirname:
break
else:
#If the above break didn't work, this part will be executed
dirpath = os.path.join(dest, root[src_prefix:], dirname)
try:
os.makedirs(dirpath,exist_ok=True)
except OSError as e:
if onerror is not None:
onerror(e)
continue #If the above else didn't executed, this will be reached
continue #If the above else didn't executed, this will be reached
This will ignore .git
directory.
Note: This requires Python >=3.2
as I used the exist_ok
option with makedirs
which isn't available on older versions.
The above answers work, but they certainly won't be hassle-free, and could easily cost you 30 minutes. If you're using Windows, the quickest method is to open the shell and use xcopy, i.e.:
c:\user> xcopy "source" "destination" /t /e
Alternatively, if you run Linux, you can use
rsync -a -f"+ */" -f"- *" source/ destination/
© 2022 - 2024 — McMap. All rights reserved.
set(path for path in files if not os.path.isdir(...))
instead. As a less effective alternative toignore
option,copy_function=lambda *a, *kw: None
could be used to disable file copying in Python 3.2+. – Veedis