2010-04-06 5 views
9

Ich habe dies die ganze Zeit getan:Python Windows-Dateikopie mit Wildcard Unterstützung

result = subprocess.call(['copy', '123*.xml', 'out_folder\\.', '/y']) 
if result == 0: 
    do_something() 
else: 
    do_something_else() 

Bis heute habe ich damit begonnen, in pywin32 Module zu suchen, dann sah ich Funktionen wie win32file.CopyFiles(), aber dann Ich habe festgestellt, dass das Kopieren von Dateien in ein Verzeichnis möglicherweise nicht unterstützt wird. Vielleicht ist diese Funktionalität irgendwo versteckt, aber ich habe es noch nicht gefunden.

Ich habe auch "glob" und "shuthil" Kombination versucht, aber "glob" ist unglaublich langsam, wenn es viele Dateien gibt.

Also, wie emulieren Sie diesen Windows-Befehl mit Python?

copy 123*.xml out_folder\. /y 

Antwort

10

Der folgende Code bietet eine portable Implementierung.

Beachten Sie, dass ich Iglob (in Python 2.5 hinzugefügt), die einen Generator erstellt, so dass es nicht die gesamte Liste der Dateien im Speicher zuerst lädt (was ist, was Glob tut).

from glob import iglob 
from shutil import copy 
from os.path import join 

def copy_files(src_glob, dst_folder): 
    for fname in iglob(src_glob): 
     copy(fname, join(dst_folder, fname)) 

if __name__=='__main__': 
    copy_files("123*.xml", "out_folder") 

Zusätzliche Dokumentation:

+0

Warum all diese Probleme mit 'copyfile'? warum nicht einfach 'copy' verwenden? – SilentGhost

+0

Warum in der Tat. Ich habe das Beispiel geändert, um Kopie anstelle von copyfile zu verwenden. Dies hat auch den zusätzlichen Vorteil, dass Berechtigungsbits ebenfalls kopiert werden. – Frederik

+2

Nur ein Hinweis, dass, wenn die Eingabedateien Pfade enthalten, der Zieldateiname mit - join (dst_folder, os.path.basename (fname)) erstellt werden muss. – geographika

3

Blick auf glob und shutil bevor es weiter gehen.

Das Teilen eines Subprozesses zum Kopieren einer Datei ist relativ ineffizient. Die Verwendung von shutil wird effizienter.

7

unter Beispiel Das ist ziemlich naiv - tut nicht überprüft, ob etwas schief geht, und erstellt keine Verzeichnisse, könnte es aber tun was Sie wollen:

import glob 
import shutil 

for path in glob.iglob('123*.xml'): 
    shutil.copy(path, 'out_folder/%s' % path) 

Siehe auch: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

Mit win32file/SHFileOperation Kopie mehr funktionsfähig zu sein scheint, sind aber nicht so tragbar und sind komplizierter zu bedienen.

1

"glob" ist unglaublich langsam, wenn es viele Dateien gibt.

glob ist langsam ist es gibt viele Ergebnisse, weil es eine riesige Liste aller Ergebnisse in einem "Big Bang" -Ansatz zurückgibt. Wenn es viele Ergebnisse gibt, wird dies viel Speicher verbrauchen und lange dauern.

Verwenden Sie stattdessen Iglob, wie von einem früheren Poster vorgeschlagen. Iglob konstruiert und gibt ein Iterator-Objekt zurück, das verwendet werden kann, um die Ergebnisse zu durchlaufen, ohne sie alle gleichzeitig im Speicher zu haben. Es ist viel effizienter, wenn es viele Übereinstimmungen gibt.

Im Allgemeinen, wenn Sie Code wie "für x in [glob.glob ...]" schreiben, sollten Sie stattdessen glob.iglob verwenden.

1
import os 
import shutil 
path=os.path.join("/home","mypath") 
destination=os.path.join("/destination","dir") 
for r,d,f in os.walk(path): 
    for files in f: 
      if files.endswith(".xml"): 
       try: 
        shutil.copy(os.path.join(r,files) , destination) 
       except IOError,e: 
        print e