shutil.copytree без файлов
Я пытаюсь использовать shutil.copytree:
shutil.copytree(SOURCE_DIR, TARGET_DIR, ignore=None)
Эта копия также файлы в папке. Мне нужно копировать только папки без каких-либо файлов. Как это сделать?
6 ответов
Вы можете сделать это, предоставив функцию "игнорировать"
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)
По сути, когда вы вызываете copytree, он рекурсивно переходит в каждую дочернюю папку и предоставляет список файлов в этой папке для функции игнорирования, чтобы проверить, подходят ли эти файлы на основе шаблона. Игнорируемые файлы будут возвращены в виде списка в конце функции, а затем copytree будет копировать только те элементы, которые не входят в этот список (который в вашем случае содержит все файлы в текущей папке).
Вот реализация решения @Oz123, которое основано на 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)
Использование distutils.dir_util.create_tree
просто скопировать структуру каталогов (не файлов)
примечание: аргумент files
список имен файлов если вы хотите что-то, что будет работать как 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)
Вы должны рассмотреть возможность использования os.walk
,
Вот пример для os.walk. Таким образом, вы можете перечислить все каталоги, а затем создать их с os.mkdir
,
Если вы хотите игнорировать функциональность шаблона с os.walk()
, затем:
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
Это будет игнорировать .git
каталог.
Примечание: это требует Python >=3.2
как я использовал exist_ok
вариант с makedirs
который недоступен в старых версиях.
Приведенные выше ответы работают, но они определенно не дадут вам никаких хлопот и могут легко стоить вам 30 минут. Если вы используете Windows, самый быстрый способ - открыть оболочку и использовать xcopy, то есть:
c:\user> xcopy "source" "destination" /t /e
В качестве альтернативы, если вы используете Linux, вы можете использовать
rsync -a -f"+ */" -f"- *" source/ destination/