Python-Mover y sobrescribir archivos y carpetas


Tengo un directorio, 'Dst Directory', que tiene archivos y carpetas en él y tengo 'src Directory' que también tiene archivos y carpetas en él. Lo que quiero hacer es mover el contenido de' src Directory ' a 'Dst Directory' y sobrescribir cualquier archivo que exista con el mismo nombre. Así por ejemplo ' Src Directorio \ archivo.txt 'necesita ser movido a' Dst Directory \ ' y sobrescribir el archivo existente.txt. Lo mismo se aplica para algunas carpetas, moviendo una carpeta y fusionando el contenido con la misma carpeta en ' dst directorio "

Actualmente estoy usando shutil.mover para mover el contenido de src a dst pero no se si los archivos ya existen y no combinar carpetas; sólo voy a poner la carpeta dentro de la carpeta existente.

Actualización: Para hacer las cosas un poco más claras; Lo que estoy haciendo es descomprimir un archivo en el directorio Dst y luego mover el contenido del Directorio Src allí y volver a comprimir, actualizando efectivamente los archivos en el archivo zip. Esto se repetirá para agregar nuevos archivos o nuevas versiones de archivos, etc, por lo que necesita sobrescribir y fusionar

Resuelto: Resolví mi problema usando 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 eso tenga sentido, ¡Gracias!

Author: Artharos, 2011-09-14

6 answers

Use copy() en su lugar, que está dispuesto a sobrescribir los archivos de destino. Si luego desea que el primer árbol desaparezca, simplemente rmtree() por separado una vez que haya terminado de iterar sobre él.

Http://docs.python.org/library/shutil.html#shutil.copy

Http://docs.python.org/library/shutil.html#shutil.rmtree

Actualización:

Haga un os.walk() sobre el árbol fuente. Para cada directorio, compruebe si existe en el lado de destino, y os.makedirs() si es faltar. Para cada archivo, simplemente shutil.copy() y el archivo será creado o sobrescrito, lo que sea apropiado.

 38
Author: Brandon Rhodes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-14 17:18:13

Esto pasará por el directorio de origen, creará cualquier directorio que no exista ya 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 será eliminado 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.

 46
Author: Ray Vega,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-15 12:46:02

Dado que nada de lo anterior funcionó para mí, así que escribí mi propia función recursiva. Llama a la función copyTree (dir1, dir2) para fusionar directorios. Ejecutar en múltiples plataformas 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)
 6
Author: ALLOY,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-10 03:16:52

Si también necesita sobrescribir archivos con el 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)
 3
Author: Vit Bernatik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-20 19:00:34

Echa un vistazo a: os.remove para eliminar archivos existentes.

 1
Author: phimuemue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-14 16:37:05

Tuve un problema similar. Quería mover archivos y estructuras de carpetas y sobrescribir archivos existentes, pero no eliminar nada que esté en la estructura de carpetas 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)
 0
Author: the,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-20 14:11:36