3 Stimmen

Rekursives Kopieren von Dateien in Unterverzeichnisse

Ich muss alle Dateien und Ordner des aktuellen Ordners in ein Unterverzeichnis kopieren. Wie kann ich dies am besten tun? Ich habe das folgende Snippet versucht, aber es schlägt fehl, wenn das Zielverzeichnis bereits existiert.

def copy(d=os.path.curdir):
    dest = "t"
    for i in os.listdir(d):
        if os.path.isdir(i):
            shutil.copytree(i, dest)
        else:
            shutil.copy(i, dest)

Ich habe das Gefühl, dass dieselbe Aufgabe besser und einfacher erledigt werden kann. Wie kann ich das tun?

0 Stimmen

Ist der Zielunterordner leer, wenn Sie den Kopiervorgang starten?

0 Stimmen

Das Snippet ist völlig fehlerhaft. 1) Was ist der Grund für die copytree auf Unterverzeichnissen und nicht auf dem Stammverzeichnis? 2) d , dest nicht verwendet werden.

0 Stimmen

@khachik sorry, hatte in Eile getippt. [2] Erledigt.

2voto

khachik Punkte 27252

Ich würde es nie mit Python machen, aber die folgende Lösung kam mir in den Sinn. Es sieht nicht einfach aus, aber es sollte funktionieren und kann vereinfacht werden (habe es nicht überprüft, sorry, kein Zugriff auf den Computer jetzt):

def copyDirectoryTree(directory, destination, preserveSymlinks=True):
  for entry in os.listdir(directory):
    entryPath = os.path.join(directory, entry)
    if os.path.isdir(entryPath):
      entrydest = os.path.join(destination, entry)
      if os.path.exists(entrydest):
        if not os.path.isdir(entrydest):
          raise IOError("Failed to copy thee, the destination for the `" + entryPath + "' directory exists and is not a directory")
        copyDirectoryTree(entrypath, entrydest, preserveSymlinks)
      else:
        shutil.copytree(entrypath, entrydest, preserveSymlinks)
    else: #symlinks and files
      if preserveSymlinks:
        shutil.copy(entryPath, directory)
      else:
        shutil.copy(os.path.realpath(entryPath), directory)

1voto

Ofir Punkte 8039

Siehe den Code in http://docs.python.org/library/shutil.html und dann ein wenig abändern (z. B. versuchen Sie: around os.makedirs(dst)).

0 Stimmen

Hmm, ich hatte gehofft, dies zu vermeiden, aber es gibt wohl keine andere Möglichkeit. Danke!

1voto

Juan Carlos Moreno Punkte 2706

Um die Antwort von mamnun zu erweitern,

Wenn Sie den direkten Aufruf des Betriebssystems verwenden wollen, würde ich Ihnen raten, cp -r zu verwenden, da Sie anscheinend eine rekursive Kopie für Verzeichnisse wünschen.

0voto

Max Punkte 3141

Müssen Sie wirklich Python verwenden? Denn die shutil-Funktionen können nicht alle Dateimetadaten und Gruppenberechtigungen kopieren. Warum versuchen Sie es nicht mit eingebauten OS-Befehlen wie cp unter Linux und xcopy in Windows?

Sie können auch versuchen, diese Befehle von Python aus auszuführen

import os

os.system("cp file1 file2")

Ich hoffe, das hilft.

0 Stimmen

Ist die Verwendung von os.system eine gute Praxis? Angenommen, ich würde darauf zurückgreifen, würde ich eine Art von Bash-Pipeing benötigen; es würde den Code plattformabhängig machen.

0 Stimmen

@khachik: für Windows xcopy Befehl verwendet werden kann. @zubin71: Nur eine andere Lösung. Und ich denke, cp y xcopy kann das Kopieren von Dateien und Verzeichnissen besser bewältigen.

0voto

fho Punkte 442

Hier ist meine Version einer rekursiven Kopiermethode für Python, scheint zu funktionieren :)

def copy_all(fr, to, overwrite=True):
  fr = os.path.normpath(fr)
  to = os.path.normpath(to)

  if os.path.isdir(fr):
    if (not os.path.exists(to + os.path.basename(fr)) and not
    os.path.basename(fr) == os.path.basename(to)):
      to += "/" + os.path.basename(fr)
      mkdirs(to)
    for file in os.listdir(fr):
      copy_all(fr + "/" + file, to + "/")
  else: #symlink or file
    dest = to
    if os.path.isdir(to):
      dest += "/"
      dest += os.path.basename(fr)

    if overwrite and (os.path.exists(dest) or os.path.islink(dest)
      rm(dest)

    if os.path.isfile(fr):
      shutil.copy2(fr, dest)
    else: #has to be a symlink
      os.symlink(os.readlink(fr), dest)  

def mkdirs(path):                                                 
  if not os.path.isdir(path):
    os.makedirs(path)

def rm(path):                                                     
  if os.path.isfile(path) or os.path.islink(path):
    os.remove(path)
  elif os.path.isdir(path):
    for file in os.listdir(path):
      fullpath = path+"/"+file
      os.rmdir(fullpath)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X