Básicamente, necesito encontrar un montón de archivos .csv y luego usar el script que escribí en todos ellos. Tengo
find . -type f -name "*.csv" | xargs ./extractdata
esto funciona pero solo procesa un archivo y no todos los archivos que necesito. ¿Ayuda?
Respuesta1
La razón por la que no funcionó es que xargs
abarrotará tantos archivos como sea posible en una línea de comando.
Por lo tanto, su secuencia de comandos "extractdata" recibirá todos los archivos a la vez y probablemente procesará solo el primer argumento. Es decir, tienes N archivos, ejecutasunoguión contodolos archivos como argumento.
Necesitas usar el -n
argumento:
... | xargs -n 1 ./extractdata
De esta manera tienes N archivos, ejecutas N scripts conunoargumento de archivo cada uno.
Sin embargo, esto es casi exactamente lo mismo que ejecutar find
con la -exec
opción (una de las diferencias es que procesa el archivo en el orden encontrado, mientras que con la tubería puede hacerlo, por ejemplo, después de pasar con sort
y/o grep
):
find ... -exec /path/to/extractdata \{\} \;
También es posible que pueda ejecutar su script en paralelo usando parallel
: esto ejecuta cuatro instancias a la vez,posiblementelo que lleva a un procesamiento más eficiente dependiendo de los datos, la RAM y el hardware:
... | parallel -n 1 -j 4 ./extractdata
(Si "extractdata" usa archivos temporales con nombres fijos, lo cual no es una buena práctica, entonces dos o más scripts que se ejecutan en paralelo escribirán sobre los archivos temporales de cada uno, estropeando las cosas).
Respuesta2
Respuesta3
Hay muchas maneras de solucionar eso, por ejemplo, podrías pedir find
que se llame al script, así:
$ find . -type f -name "*.csv" -exec your_script {} ;
{} es el nombre del archivo que se encontró cada vez.
Es posible que necesites escapar de esos caracteres:
$ find . -type f -name "*.csv" -exec your_script \{\} \;