2010-07-13 25 views
5

, así que tengo una secuencia de comandos python que toma el nombre de archivo como un argumento de comando y procesa ese archivo. Sin embargo, dado que tengo 263 archivos que necesitan el mismo procesamiento, me preguntaba si la sección del argumento del comando podría modificarse con un bucle for para ejecutar consecutivamente todos los archivos en una carpeta. Saludos, SatModifique la secuencia de comandos python para que se ejecute en cada archivo en un directorio

EDIT:

El código para el argumento sistema está aquí:

try: 
    opt_list, args = getopt.getopt(sys.argv[1:], 'r:vo:A:Cp:U:eM:') 

except getopt.GetoptError, msg: 
    print 'prepare_receptor4.py: %s' %msg 
    usage() 
    sys.exit(2) 

con 'r' es el nombre del archivo que necesita ser procesada y los otros son argumentos opcionales. No estoy seguro de cómo modificar esto con un bucle for.

Respuesta

9

Como una cuestión práctica, cualquiera que sea el shell que está utilizando probablemente tiene una sintaxis que se puede utilizar fácilmente para esto. En Bash, por ejemplo:

for f in *; do python myscript.py $f; done 

Para hacer esto realidad en Python, me gustaría sugerir la estructuración de su programa para que el código principal se encuentra en una función que toma un argumento, el nombre de archivo.

def process(filename): 
    ...code goes here... 

Entonces puede invocar esta función como tal,

for f in os.listdir(folder): 
    process(f) 

folder podría pasar como un argumento de línea de comandos, o simplemente escribe en la secuencia de comandos (si no es algo que uno se vuelve a utilizar)

EDITAR: En respuesta a su edición, me gustaría sugerir sólo dar los nombres de archivo como argumentos de línea de comandos regulares, sin utilizar la opción -r, por lo que van a terminan en args. A continuación, puede hacer

for f in args: 
    process(f) 

o si prefiere pasar el nombre de directorio que el argumento de línea de comandos,

for d in args: 
    for f in os.listdir(d): 
     process(f) 

Alternativamente, supongo que se podría pasar varias instancias de la opción -r, y luego hacer

for opt, arg in opt_list: 
    if opt == '-r': 
     process(arg) 
+0

Saludos, me trataron de modificar el código (para la diversión y la experiencia), pero terminaron rompiendo ... así que utiliza el bucle en bash que funcionó una delicia! Sab –

1

Sí, podría modificarlo así. Pasa por los argumentos en lugar de indexar el primer elemento.

4

os.walk() suena como que podría trabajar aquí.

def traverse_and_touch(directory, touch): 
    ''' 
    General function for traversing a local directory. Walks through 
    the entire directory, and touches all files with a specified function. 
    ''' 
    for root, dirs, files in os.walk(directory): 
    for filename in files: 
     touch(os.path.join(root, filename)) 
    return 

Ahora, todo lo que necesita hacer es pase en el directorio desea recorrer y una función que va a realizar y el código en cada archivo.

os.walk() también atraviesa todos los subdirectorios.

3

Cuando estoy trabajando en varios archivos/carpetas, que suelen utilizar os.walk:

import os 
for root, dirs, files in os.walk(dir): 
    for fname in files: 
     do_something(fname) 

Obtener el directorio de getopt o optparse. Además, puede construir una ruta absoluta con os.path.abspath si lo necesita.

current_file = "%s%s%s" % (os.path.abspath(root), os.path.sep, fname) 
do_something(current_file) 
1

Sugiero que su "principal" debe procesar cada archivo dado después de las opciones. Es decir, en la variable "args". No pase caminos con "-r", esto limita su flexibilidad. Si usa os.walk() etc. en el programa, necesita que el sistema funcione solo en árboles de archivos, lo que hace que sea más difícil de personalizar y desarrollar.

Si el programa funciona con una lista de rutas, es muy fácil de usar de diferentes maneras. Por ejemplo, puede listar un archivo de datos para probar. Para procesar un directorio haga "myprogram dir/*. Dat". Para procesar un árbol de archivos, use las comillas inversas:

myprogram `find . -name "*.dat"` 

Por último, puede realizar un procesamiento en paralelo muy económico. Algo como:

find . -name '*.dat' | xargs -P 5 myprogram 

Cinco copias de su programa se ejecutan en paralelo. No es necesario el bloqueo o las horquillas o los hilos u otra sincronización.

(anterior se supone que está en un sistema de tipo Linux/OSX.)

Cuestiones relacionadas