importar - Python: mueve y sobrescribe archivos y carpetas
importar clases en python (6)
Tengo un directorio, ''Dst Directory'', que tiene archivos y carpetas y tengo ''src Directory'', que también tiene archivos y carpetas. Lo que quiero hacer es mover los contenidos de ''src Directory'' a ''Dst Directory'' y sobrescribir cualquier archivo que exista con el mismo nombre. Entonces, por ejemplo, ''Src Directory / file.txt'' debe moverse a ''Dst Directory'' y sobrescribir el archivo existente .txt. Lo mismo aplica para algunas carpetas, moviendo una carpeta y fusionando los contenidos con la misma carpeta en ''dst directory''
Actualmente estoy usando shutil.move para mover los contenidos de src a dst pero no lo hará si los archivos ya existen y no fusionará carpetas; simplemente colocará la carpeta dentro de la carpeta existente.
Actualización: para aclarar un poco las cosas; Lo que estoy haciendo es descomprimir un archivo en el Directorio Dst y luego mover los contenidos del Directorio Src allí y volver a realizar la actualización, actualizando de manera efectiva los archivos en el archivo zip. Esto se repetirá para agregar nuevos archivos o nuevas versiones de archivos, etc. Por eso es necesario sobrescribir y fusionar
Resuelto: resolví mi problema utilizando distutils.dir_util.copy_tree (src, dst), esto copia las carpetas y archivos del directorio src al directorio dst y sobrescribe / fusiona donde sea necesario. Espero que ayude a algunas personas!
Espero que tenga sentido, gracias!
Como ninguno de los anteriores funcionó para mí, entonces escribí mi propia función recursiva. Llamar a la función copyTree (dir1, dir2) para fusionar directorios. Ejecutar en plataformas multiples Linux y Windows.
def forceMergeFlatDir(srcDir, dstDir):
if not os.path.exists(dstDir):
os.makedirs(dstDir)
for item in os.listdir(srcDir):
srcFile = os.path.join(srcDir, item)
dstFile = os.path.join(dstDir, item)
forceCopyFile(srcFile, dstFile)
def forceCopyFile (sfile, dfile):
if os.path.isfile(sfile):
shutil.copy2(sfile, dfile)
def isAFlatDir(sDir):
for item in os.listdir(sDir):
sItem = os.path.join(sDir, item)
if os.path.isdir(sItem):
return False
return True
def copyTree(src, dst):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isfile(s):
if not os.path.exists(dst):
os.makedirs(dst)
forceCopyFile(s,d)
if os.path.isdir(s):
isRecursive = not isAFlatDir(s)
if isRecursive:
copyTree(s, d)
else:
forceMergeFlatDir(s, d)
Eche un vistazo a: os.remove
para eliminar los archivos existentes.
Esto pasará por el directorio de origen, creará cualquier directorio que no exista en el directorio de destino y moverá los archivos desde el origen al directorio de destino:
import os
import shutil
root_src_dir = ''Src Directory//'
root_dst_dir = ''Dst Directory//'
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.move(src_file, dst_dir)
Cualquier archivo preexistente se eliminará primero (a través de os.remove
) antes de ser reemplazado por el archivo fuente correspondiente. Cualquier archivo o directorio que ya exista en el destino pero no en el origen permanecerá intacto.
Si también necesita sobreescribir archivos con indicador de solo lectura, use esto:
def copyDirTree(root_src_dir,root_dst_dir):
"""
Copy directory tree. Overwrites also read only files.
:param root_src_dir: source directory
:param root_dst_dir: destination directory
"""
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):
try:
os.remove(dst_file)
except PermissionError as exc:
os.chmod(dst_file, stat.S_IWUSR)
os.remove(dst_file)
shutil.copy(src_file, dst_dir)
Tuve un problema similar. Quería mover archivos y estructuras de carpetas y sobrescribir los archivos existentes, pero no eliminar nada que esté en la estructura de la carpeta de destino.
Lo resolví usando os.walk()
, llamando recursivamente a mi función y usando shutil.move()
en archivos que quería sobrescribir y carpetas que no existían.
Funciona como shutil.move()
, pero con la ventaja de que los archivos existentes solo se sobrescriben, pero no se eliminan.
import os
import shutil
def moverecursively(source_folder, destination_folder):
basename = os.path.basename(source_folder)
dest_dir = os.path.join(destination_folder, basename)
if not os.path.exists(dest_dir):
shutil.move(source_folder, destination_folder)
else:
dst_path = os.path.join(destination_folder, basename)
for root, dirs, files in os.walk(source_folder):
for item in files:
src_path = os.path.join(root, item)
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.move(src_path, dst_path)
for item in dirs:
src_path = os.path.join(root, item)
moverecursively(src_path, dst_path)
Use copy()
, que está dispuesto a sobrescribir los archivos de destino. Si luego quieres que el primer árbol se vaya, simplemente rmtree()
por separado una vez que hayas terminado de iterar sobre él.
http://docs.python.org/library/shutil.html#shutil.copy
http://docs.python.org/library/shutil.html#shutil.rmtree
Actualizar:
Haz un os.walk()
sobre el árbol fuente. Para cada directorio, verifique si existe en el lado del destino, y os.makedirs()
si falta. Para cada archivo, simplemente shutil.copy()
y el archivo se creará o sobrescribirá, según corresponda.