2010-04-06 14 views
9

que he estado haciendo esto todo el tiempo:pitón de Windows Copia de archivos con soporte Comodín

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

Hasta hoy comenzó a buscar en módulos pywin32, entonces vi funciones como win32file.CopyFiles(), pero luego Descubrí que no es compatible con la copia de archivos en un directorio. Tal vez esta funcionalidad esté oculta en algún lado, pero aún no la he encontrado.

También probé la combinación "glob" y "shutil", pero "glob" es increíblemente lenta si hay muchos archivos.

Entonces, ¿cómo se emula este comando de Windows con Python?

copy 123*.xml out_folder\. /y 

Respuesta

10

El siguiente código proporciona una implementación portátil.

Tenga en cuenta que estoy usando iglob (agregado en Python 2.5) que crea un generador, por lo que no carga primero toda la lista de archivos en la memoria (que es lo que glob hace).

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

documentación adicional:

+0

¿por qué todos estos problemas con 'copyfile'? ¿por qué no usar 'copy'? – SilentGhost

+0

¿Por qué? Cambié el ejemplo para usar copy en lugar de copyfile. Esto también tiene la ventaja adicional de que también se copian los bits de permiso. – Frederik

+2

Solo tenga en cuenta que si los archivos de entrada contienen rutas, entonces el nombre de archivo de destino debe crearse usando - join (dst_folder, os.path.basename (fname)) – geographika

3

Mira glob y shutil antes de seguir adelante.

Bifurcar un subproceso para copiar un archivo es relativamente ineficiente. Usar shutil será más eficiente.

7

El ejemplo a continuación es bastante ingenuo - no hace ninguna comprobación de si algo va mal, y no crea ningún directorio, pero podría hacer lo que quiere:

import glob 
import shutil 

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

Ver también: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html

Usando copia win32file/SHFileOperation parece ser más funcional, pero no son tan portátil y es más complicado de usar.

1

"glob" es increíblemente lento si hay muchos archivos.

glob es lento, hay muchos resultados porque devuelve una gran lista de todos los resultados en un enfoque de "big bang". Si hay muchos resultados, esto consumirá mucha memoria y llevará mucho tiempo.

Use iglob en su lugar, como lo sugiere un póster anterior. iglob construye y devuelve un objeto iterador que se puede utilizar para recorrer los resultados, sin tenerlos todos en memoria al mismo tiempo. Es mucho más eficiente si hay muchas coincidencias.

En general, siempre que escriba código como "para x en [glob.glob ...]" debería usar glob.iglob en su lugar.

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 
Cuestiones relacionadas