2010-04-06 7 views
9

Ho fatto questo per tutto il tempo:Python di Windows Copia file con supporto jolly

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

Fino ad oggi ho iniziato a cercare in moduli pywin32, poi ho visto le funzioni come win32file.CopyFiles(), ma poi Ho scoperto che potrebbe non supportare la copia di file in una directory. Forse questa funzionalità è nascosta da qualche parte, ma non l'ho ancora trovata.

Ho anche provato la combinazione "glob" e "shutil", ma "glob" è incredibilmente lento se ci sono molti file.

Quindi, come si emula questo comando di Windows con Python?

copy 123*.xml out_folder\. /y 

risposta

10

Il seguente codice fornisce un'implementazione portatile.

Nota che sto usando iglob (aggiunto in Python 2.5) che crea un generatore, quindi non carica prima l'intero elenco di file in memoria (che è ciò che fa glob).

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") 

Ulteriore documentazione:

+0

perché tutti questi problemi con 'copyfile'? perché non usare solo 'copia'? – SilentGhost

+0

Perché davvero. Ho modificato l'esempio per utilizzare la copia anziché il file di copia. Questo ha anche il vantaggio aggiunto che anche i bit di autorizzazione vengono copiati. – Frederik

+2

Solo una nota che se i file di input contengono percorsi, il nome del file di destinazione deve essere creato usando - join (dst_folder, os.path.basename (fname)) – geographika

3

Guardate glob e shutil prima di andare avanti.

Il fork di un sottoprocesso per copiare un file è relativamente inefficiente. L'utilizzo di shutil sarà più efficiente.

7

Il sotto esempio è abbastanza ingenuo - non fa alcuna verifica se qualcosa va storto, e non crea directory, ma potrebbe fare ciò che si vuole:

import glob 
import shutil 

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

Vedi anche: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

Utilizzando copia win32file/SHFileOperation sembra essere più funzionale, ma non sono più portabile e sono più complicato da usare.

1

"glob" è incredibilmente lento se ci sono molti file.

glob è lento è ci sono molti risultati perché restituisce una lista enorme di tutti i risultati in un approccio "big bang". Se ci sono molti risultati, questo richiederà molta memoria e richiederà molto tempo.

Utilizzare invece l'iglob, come suggerito da un poster precedente. iglob costruisce e restituisce un oggetto iteratore che può essere utilizzato per scorrere i risultati, senza averli mai tutti in memoria nello stesso momento. È molto più efficiente se ci sono molte partite.

In generale, ogni volta che si scrive codice come "per x in [glob.glob ...]" si dovrebbe usare glob.iglob invece.

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 
Problemi correlati