Este sitiopresenta el xargs
comando con una -J
opció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) -I
difieren -J
en 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 rm
or mkdir
pueden 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 -J
bandera para la versión BSD, xargs
no creo que haya una opción exactamente equivalente para GNU xargs
. -J
reemplaza 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: -I
1 . 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 -I
como reemplazo directo. Pero su ejemplo usa rsync
y estoy seguro de que no desea múltiples invocaciones de eso.
Su mejor curso de acción entonces es considerar alternativas que comiencen con find
y la acción -exec
o -execdir
. Hay dos variaciones de estos. Uno es análogo a GNU -I
y 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 -I
una función similar a -J
GNU -I
! Pero esto -I
se ve afectado por otras banderas y lo más probable es que no sea lo que estás buscando.