Opción Xargs `-J`

Opción Xargs `-J`

Este sitiopresenta el xargscomando con una -Jopción que permite pasar la entrada estándar a una posición deseada en el argumento del comando:

find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/

pero en unPágina de manual de GNU xargsesta opción no está presente.

¿Cuál es la forma de hacer esto para los comandos que aceptan esto?

Respuesta1

No estoy seguro de que esto sea lo que esperaba, pero en el mundo BSD (como macOS) -Idifieren -Jen la forma en que pasan las múltiples "líneas" al comando. Ejemplo:

$ ls
file1 file2 file3

$ find . -type f -print0 | xargs -I % rm %
rm file1
rm file2
rm file3

$ find . -type f -print0 | xargs -J % rm %
rm file1 file2 file3

Entonces, con -I, xargs ejecutará el comando para cada elemento que se le pase individualmente. Con -J, xargs ejecutará el comando una vez y concatenará todos los elementos y los pasará como argumentos todos juntos.

Algunos comandos como rmor mkdirpueden tomar múltiples argumentos y actuar sobre ellos de la misma manera que si pasara un solo argumento y los ejecutara varias veces. Pero algunas aplicaciones pueden cambiar dependiendo de cómo les pases los argumentos. Por ejemplo el tar. Puede crear un archivo tar y luego agregarle archivos o puede crear un archivo tar agregándole todos los archivos de una sola vez.

$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %

Respuesta2

Si esta es la -Jbandera para la versión BSD, xargsno creo que haya una opción exactamente equivalente para GNU xargs. -Jreemplaza una única aparición dereplstr(p. ej %.) con cada línea ingresando a través de la entrada estándar. La versión GNU tiene unasimilaropción, sin embargo: -I1 . Sin embargo, puedes utilizarreplstrvarias veces con esa bandera.

Para casos de uso en los que no es importante si hay una o varias invocaciones de comandos, debería poder usar GNU xargs -Icomo reemplazo directo. Pero su ejemplo usa rsyncy estoy seguro de que no desea múltiples invocaciones de eso.

Su mejor curso de acción entonces es considerar alternativas que comiencen con findy la acción -execo -execdir. Hay dos variaciones de estos. Uno es análogo a GNU -Iy el otro a BSD -J. Echa un vistazo a estos ejemplos...

# Note the escaping of ';'
$ find /tmp -name '*.txt' -exec echo {} \;
/tmp/a.txt
/tmp/b.txt
..
/tmp/z.txt

Ahora compare eso con esto:

$ find /tmp -name '*.txt' -exec echo {} +
/tmp/a.txt /tmp/b.txt .. /tmp/z.txt

La única diferencia entre los dos es qué "modificador" aparece al final, +o ;.

1 ¡ Más cosas confusas es que la versión BSD también tiene -Iuna función similar a -JGNU -I! Pero esto -Ise ve afectado por otras banderas y lo más probable es que no sea lo que estás buscando.

información relacionada