Copie archivos o directorios recursivamente en Python

Python parece tener funciones para copiar archivos (por ejemplo, shutil.copy ) y funciones para copiar directorios (por ejemplo, shutil.copytree ) pero no he encontrado ninguna función que maneje ambos. Claro, es trivial comprobar si desea copiar un archivo o un directorio, pero parece una extraña omisión.

¿Realmente no existe una función estándar que funcione como el comando unix cp -r , es decir, admite directorios y archivos y copias de forma recursiva? ¿Cuál sería la forma más elegante de solucionar este problema en Python?

Le sugiero que primero llame a shutil.copytree , y si se produce una excepción, shutil.copy a intentarlo con 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 

Para agregar las respuestas de Tzot y gns , aquí hay una forma alternativa de copiar archivos y carpetas de forma recursiva. (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) 

Si es tu primera vez y no tienes idea de cómo copiar archivos y carpetas de forma recursiva, espero que esto te ayude.

Unix cp no ‘soporta directorios y archivos’:

 betelgeuse:tmp james$ cp source/ dest/ cp: source/ is a directory (not copied). 

Para hacer que cp copie un directorio, debe indicarle manualmente a cp que se trata de un directorio, usando la marca ‘-r’.

Sin embargo, aquí hay algunas desconexiones: cp -r cuando se pasa un nombre de archivo, ya que la fuente copiará felizmente solo el archivo; Copytree no lo hará.

shutil.copy y shutil.copy2 están copiando archivos.

shutil.copytree copia una carpeta con todos los archivos y todas las subcarpetas. shutil.copytree está utilizando shutil.copy2 para copiar los archivos.

Así que el análogo a cp -r que está diciendo es shutil.copytree porque cp -r apunta y copia una carpeta y sus archivos / subcarpetas como shutil.copytree . Sin el -r cp copia archivos como shutil.copy y shutil.copy2 do.

Creo que copy_tree es lo que buscas

El método de python shutil.copytree es un desastre. He hecho uno que funciona correctamente:

 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('..')