2009-06-16 17 views
8

He dividido un archivo de texto grande en una serie de conjuntos más pequeños para las pruebas de rendimiento que estoy haciendo. Hay una serie de directorios así:Bash: cómo atravesar la estructura del directorio y ejecutar comandos?

/home/brianly/output-02 (contains 2 files myfile.chunk.00 and myfile.chunk.01) 
/home/brianly/output-04 (contains 4 files...) 
/home/brianly/output-06 (contains 6 files...) 

Es importante tener en cuenta que hay un número creciente de archivos en cada directorio. Lo que tengo que hacer es ejecutar un ejecutable contra cada uno de los archivos de texto en los directorios de salida. El comando se ve algo como esto en contra de un solo archivo:

./myexecutable -i /home/brianly/output-02/myfile.chunk.00 -o /home/brianly/output-02/myfile.chunk.00.processed 

Aquí el parámetro -i es el archivo de entrada y parámetro -o es la ubicación de salida.

En C# Me gustaría recorrer los directorios para obtener la lista de archivos en cada carpeta, y luego recorrerlos para ejecutar las líneas de comando. ¿Cómo atravieso una estructura de directorios como esta usando bash, y ejecuto el comando con los parámetros correctos basados ​​en la ubicación y los archivos en esa ubicación?

Respuesta

8

Para este tipo de cosa que siempre utilice encuentran junto con xargs:

$ find output-* -name "*.chunk.??" | xargs -I{} ./myexecutable -i {} -o {}.processed 

Ahora que su script procesa sólo un archivo a la vez, usando -exec (o -execdir) directamente con encontrar, como ya se ha sugerido, es tan eficiente, pero estoy acostumbrado a usar xargs , ya que es en general mucho más eficiente al alimentar un comando que opera en muchos argumentos a la vez. Por lo tanto, es una herramienta muy útil para guardar en el cinturón de herramientas, así que pensé que debería mencionarse.

7

Algo así como:

for x in `find /home/brianonly -type f` 
do 
./yourexecutable -i $x -o $x.processed 
done 
+0

hay respaldo garrapatas antes y después de encontrar f – nikudesu

+1

para x en $ (encontrar/home/brianonly type f); do ... hecho $() es _so_ mucho más legible que back-ticks. Mi $ .02. –

+0

Creo que el suyo trataría de procesar los archivos procesados. –

2

Como otros han sugerido, utilice find(1):

# Find all files named 'myfile.chunk.*' but NOT named 'myfile.chunk.*.processed' 
# under the directory tree rooted at base-directory, and execute a command on 
# them: 
find base-directory -name 'output.*' '!' -name 'output.*.processed' -exec ./myexecutable -i '{}' -o '{}'.processed ';' 
1

Según la información proporcionada, parece que esta sería una traducción completamente directa de su idea de C#.

for i in /home/brianly/output-*; do 
    for j in "$i/"*.[0-9][0-9]; do 
     ./myexecutable -i "$j" -o "$j.processed" 
    done 
done 
Cuestiones relacionadas