Скопируйте файл или каталоги рекурсивно в Python
У Python есть функции для копирования файлов (например, shutil.copy
) и функций для копирования каталогов (например, shutil.copytree
), но я не нашел никакой функции, которая обрабатывает оба. Конечно, тривиально проверить, хотите ли вы скопировать файл или каталог, но это похоже на странное упущение.
Нет ли стандартной функции, которая работает как команда unix cp -r
, т.е. рекурсивно поддерживает как каталоги, так и файлы и копии? Какой был бы самый элегантный способ обойти эту проблему в Python?
Ответы
Ответ 1
Я предлагаю вам сначала вызвать shutil.copytree
, и если вызывается исключение, повторите попытку с shutil.copy
.
import shutil, errno
def copyanything(src, dst):
try:
shutil.copytree(src, dst)
except OSError as exc: # python >2.5
if exc.errno == errno.ENOTDIR:
shutil.copy(src, dst)
else: raise
Ответ 2
Unix cp
не поддерживает обе каталоги и файлы:
betelgeuse:tmp james$ cp source/ dest/
cp: source/ is a directory (not copied).
Чтобы сделать cp скопировать каталог, вам нужно вручную указать cp, что это каталог, используя флаг '-r'.
Здесь есть некоторая отключаемость - cp -r
при передаче имени файла, так как источник с радостью копирует только один файл; copytree не будет.
Ответ 3
Чтобы добавить в Tzot и gns ответы, здесь альтернативный способ копирования файлов и папок рекурсивно. (Python 3.X)
import os, shutil
root_src_dir = r'C:\MyMusic' #Path/Location of the source directory
root_dst_dir = 'D:MusicBackUp' #Path to the destination folder
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.copy(src_file, dst_dir)
Если это ваш первый раз, и вы не знаете, как копировать файлы и папки рекурсивно, я надеюсь, что это поможет.
Ответ 4
shutil.copy
и shutil.copy2
- копирование файлов.
shutil.copytree
копирует папку со всеми файлами и всеми подпапками. shutil.copytree
использует shutil.copy2
для копирования файлов.
Таким образом, аналогом cp -r
, который вы говорите, является shutil.copytree
, потому что cp -r
нацеливает и копирует папку и ее файлы/подпапки, например shutil.copytree
. Без -r
cp
копировать файлы типа shutil.copy
и shutil.copy2
do.
Ответ 5
Метод python shutil.copytree - это беспорядок. Я сделал один, который работает правильно:
def copydirectorykut(src, dst):
os.chdir(dst)
list=os.listdir(src)
nom= src+'.txt'
fitx= open(nom, 'w')
for item in list:
fitx.write("%s\n" % item)
fitx.close()
f = open(nom,'r')
for line in f.readlines():
if "." in line:
shutil.copy(src+'/'+line[:-1],dst+'/'+line[:-1])
else:
if not os.path.exists(dst+'/'+line[:-1]):
os.makedirs(dst+'/'+line[:-1])
copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
f.close()
os.remove(nom)
os.chdir('..')