it-swarm.com.de

Python - Verschieben und Überschreiben von Dateien und Ordnern

Ich habe ein Verzeichnis, 'Dst Directory', das Dateien und Ordner enthält, und ich habe 'src Directory', das auch Dateien und Ordner enthält. Ich möchte den Inhalt von 'src Directory' in 'Dst Directory' verschieben und alle Dateien überschreiben, die mit demselben Namen existieren. So muss zum Beispiel 'Src Directory\file.txt' in 'Dst Directory \' verschoben werden und die vorhandene Datei.txt überschreiben. Dasselbe gilt für einige Ordner: Verschieben eines Ordners und Zusammenführen des Inhalts mit demselben Ordner im 'dst-Verzeichnis'

Ich verwende derzeit shutil.move, um den Inhalt von src nach dst zu verschieben. Dies ist jedoch nicht der Fall, wenn die Dateien bereits vorhanden sind und Ordner nicht zusammengeführt werden. Der Ordner wird einfach in den vorhandenen Ordner eingefügt.

Update: Um es etwas klarer zu machen; Was ich mache, ist das Entpacken eines Archivs in das Dst-Verzeichnis und das Verschieben des Inhalts des Src -Verzeichnisses dorthin, das Neipipping und das Aktualisieren der Dateien im Zip-Archiv. Dies wird wiederholt, um neue Dateien oder neue Versionen von Dateien usw. hinzuzufügen. Deshalb muss es überschrieben und zusammengeführt werden

Behoben: Ich habe mein Problem durch die Verwendung von distutils.dir_util.copy_tree (src, dst) gelöst. Dies kopiert die Ordner und Dateien aus dem src-Verzeichnis in das dst-Verzeichnis und überschreibt/überschreibt, wo nötig. Hoffe das hilft einigen Leuten!

Hoffe, das macht Sinn, danke!

59
Artharos

Verwenden Sie stattdessen copy(), um die Zieldateien zu überschreiben. Wenn Sie möchten, dass der erste Baum verschwindet, müssen Sie ihn nur noch rmtree() trennen, sobald Sie ihn durchlaufen haben.

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

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

Update:

Führen Sie eine os.walk() über der Quellstruktur aus. Überprüfen Sie für jedes Verzeichnis, ob es auf der Zielseite vorhanden ist, und os.makedirs(), falls es fehlt. Für jede Datei einfach shutil.copy() und die Datei wird erstellt oder überschrieben, je nachdem, was angemessen ist.

41
Brandon Rhodes

Dadurch wird das Quellverzeichnis durchlaufen, alle Verzeichnisse erstellt, die noch nicht im Zielverzeichnis vorhanden sind, und die Dateien von der Quelle in das Zielverzeichnis verschieben:

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):
            # in case of the src and dst are the same file
            if os.path.samefile(src_file, dst_file):
                continue
            os.remove(dst_file)
        shutil.move(src_file, dst_dir)

Vorhandene Dateien werden zuerst entfernt (über os.remove), bevor sie durch die entsprechende Quelldatei ersetzt werden. Dateien oder Verzeichnisse, die bereits im Ziel, aber nicht in der Quelle vorhanden sind, bleiben davon unberührt.

50
Ray Vega

Da keiner der oben genannten Punkte für mich funktionierte, schrieb ich meine eigene rekursive Funktion. Rufen Sie die Funktion copyTree (dir1, dir2) auf, um Verzeichnisse zusammenzuführen. Auf mehreren Plattformen Linux und Windows ausführen. 

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
ALLOY

Wenn Sie Dateien auch mit schreibgeschütztem Flag überschreiben müssen, verwenden Sie Folgendes:

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
Vit Bernatik

Schauen Sie sich folgende Dateien an: os.remove , um vorhandene Dateien zu entfernen.

1
phimuemue

Ich hatte ein ähnliches Problem. Ich wollte Dateien und Ordnerstrukturen verschieben und vorhandene Dateien überschreiben, aber nichts löschen, was sich in der Zielordnerstruktur befindet.

Ich habe das Problem gelöst, indem ich os.walk() verwendet habe, um meine Funktion rekursiv aufzurufen und shutil.move() für Dateien zu verwenden, die ich überschreiben wollte, und Ordner, die nicht vorhanden waren.

Es funktioniert wie shutil.move(), jedoch mit dem Vorteil, dass vorhandene Dateien nur überschrieben, aber nicht gelöscht werden.

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
the