GNU parallel
es una variante de xargs
. Ambos tienen interfaces muy similares, y si buscas ayuda en parallel
, puede que tengas más suerte buscando información sobre xargs
.
Dicho esto, la forma en que ambos funcionan es bastante simple. Con su comportamiento predeterminado, ambos programas leen la entrada de STDIN, luego dividen la entrada en tokens basados en espacios en blanco. Cada uno de estos tokens se pasa luego a un programa proporcionado como argumento. El valor predeterminado para xargs es pasar tantos tokens como sea posible al programa, y luego iniciar un nuevo proceso cuando se alcanza el límite. No estoy seguro de cómo funciona el valor predeterminado para paralelo.
Aquí se muestra un ejemplo:
> echo "foo bar \
baz" | xargs echo
foo bar baz
Hay algunos problemas con el comportamiento por defecto, por lo que es común ver algunas variaciones.
El primer problema es que debido a que se usa el espacio en blanco para tokenizar, cualquier archivo con espacios en blanco provocará la ruptura de paralelo y xargs. Una solución es tokenizar alrededor del carácter NULL en su lugar. find
incluso proporciona una opción para hacer esto es fácil de hacer:
> echo "Success!" > bad\ filename
> find . "bad\ filename" -print0 | xargs -0 cat
Success!
La opción -print0
dice find
para separar los archivos con el carácter nulo en lugar de espacios en blanco.
La opción -0
dice xargs
para usar el carácter NULO para tokenizar cada argumento.
Tenga en cuenta que parallel
es un poco mejor que en que su comportamiento predeterminado es el tokenizar alrededor de las nuevas líneas, por lo que hay menos necesidad de cambiar el comportamiento predeterminado.
Otro problema común es que es posible que desee controlar cómo se pasan los argumentos a xargs
o parallel
. Si necesita tener una ubicación específica de los argumentos pasados al programa, puede usar {}
para especificar dónde se colocará el argumento.
> mkdir new_dir
> find -name *.xml | xargs mv {} new_dir
Esto moverá todos los archivos en el directorio actual y los subdirectorios al directorio new_dir. En realidad se descompone en los siguientes:
> find -name *.xml | xargs echo mv {} new_dir
> mv foo.xml new_dir
> mv bar.xml new_dir
> mv baz.xml new_dir
por lo que teniendo en cuenta cómo xargs
y parallel
trabajo, que es de esperar debería ser capaz de ver el asunto con su comando. find . -name '*.xml'
generará una lista de archivos xml para pasar al programa script.sh
.
> find . -name '*.xml' | parallel -j2 echo script.sh {}
> script.sh foo.xml
> script.sh bar.xml
> script.sh baz.xml
Sin embargo, ls | parallel -j2 script.sh {}
generará una lista de todos los archivos en el directorio actual al ser pasado al programa de script.sh.
> ls | parallel -j2 echo script.sh {}
> script.sh some_directory
> script.sh some_file
> script.sh foo.xml
> ...
Una variante más correcto de la versión ls
sería de la siguiente manera:
> ls *.xml | parallel -j2 script.sh {}
Sin embargo, e importante diferencia entre esta y la versión hallazgo es que la hallan será buscar a través de todos los subdirectorios para archivos, mientras Solo buscará en el directorio actual. La versión equivalente find
del comando anterior ls
sería de la siguiente manera:
> find -maxdepth 1 -name '*.xml'
Esto sólo buscará en el directorio actual.
¡ha intentado correr con #!/ bin/bash -x que te mostrará si tus argumentos no son lo que crees que deberían ser. –
Siempre estoy avergonzado cuando sucede esto, pero cuando traté de reproducir este problema al día siguiente (y uso el -x como se sugiere) no pude reproducirlo y todo estaba funcionando bien. He podido usar ls o encontrar con éxito todo el tiempo. Me pregunto si, de alguna manera, reventé mi entorno y un cierre/sesión borró algo. – Dave