La diferencia está en qué datos está aceptando el programa de destino.
Si solo usa una tubería, recibe datos en STDIN (el flujo de entrada estándar) como una pila de datos sin procesar que puede ordenar a través de una línea a la vez. Sin embargo, algunos programas no aceptan sus comandos de forma estándar, esperan que se especifique en los argumentos del comando. Por ejemplo touch
toma un nombre de archivo como un parámetro en la línea de comandos, así: touch file1.txt
.
Si usted tiene un programa que da salida a los nombres de archivo de salida estándar y desea utilizarlas como argumentos a touch
, usted tiene que utilizar xargs
el que lee los datos de la secuencia STDIN y convierte cada línea en el espacio separadas argumentos para el comando.
Estas dos cosas son equivalentes:
# touch file1.txt
# echo file1.txt | xargs touch
No lo use a xargs
menos que sepa exactamente lo que está haciendo y por qué es necesario. Es frecuente que haya una mejor manera de hacer el trabajo que usar xargs
para forzar la conversión. El proceso de conversión también está plagado de posibles dificultades como el escape y la expansión de palabras, etc.
xargs
y$(...)
), xargs es mucho más seguro que la sustitución de comandos. Y no recuerdo haber encontrado un nombre de archivo legítimo con una nueva línea. ¿No son los problemas de escape y expansión de palabras problemas con la sustitución de comandos, no xargs?xargs -0
), lo cual es útil junto confind -print0
.xargs
Llama al programa a través del shell con argumentos separados por espacios, o realmente construye la lista de argumentos internamente (por ejemplo, para usar conexecv
/execp
)?-d \n
, aunque BSD xargs (OSX et al) no parece admitir esta opción.Para ampliar las respuestas ya proporcionadas,
xargs
puede hacer una cosa interesante que se está volviendo cada vez más importante en el panorama informático distribuido y multinúcleo de hoy: puede paralelar procesos de trabajo.Por ejemplo:
codificará * .wav => * .flac, utilizando tres procesos a la vez (
-P 3
).fuente
-exec
parámetro no procesará trabajos en paralelo.-0
argumentoxargs
hace que considere que elNULL
carácter es el delimitador del elemento de entrada.find -print0
salida de elementos delimitados por NULL. Esta es una gran práctica para los nombres de archivo que pueden contener espacios, comillas u otros caracteres especiales.xargs es particularmente útil cuando tienes una lista de rutas de archivos en stdin y quieres hacer algo con ellas. Por ejemplo:
Examinemos esto paso a paso:
En otras palabras, nuestra entrada es una lista de caminos en los que queremos hacer algo.
Para saber qué hace xargs con estas rutas, un buen truco es agregar
echo
antes de su comando, así:El
-n 1
argumento hará que xargs convierta cada línea en un comando propio. Elsed -i "s/color/colour/g"
comando reemplazará todas las apariciones decolor
concolour
para el archivo especificado.Tenga en cuenta que esto solo funciona si no tiene espacios en sus caminos. Si lo hace, debe usar rutas terminadas nulas como entrada a xargs pasando la
-0
bandera. Un ejemplo de uso sería:Lo que hace lo mismo que describimos anteriormente, pero también funciona si uno de los caminos tiene un espacio.
Esto funciona con cualquier comando que produce nombres de archivo como salida como
find
olocate
. Sin embargo, si lo usa en un repositorio de git con muchos archivos, podría ser más eficiente usarlo engit grep -l
lugar degit ls-files
, de esta manera:El
git grep -l "color" "*.tex"
comando dará una lista de archivos "* .tex" que contienen la frase "color".fuente
Su primer argumento ilustra la diferencia bastante bien.
\ls | grep Cases | less
le permite explorar la lista de nombres de archivos producidos porls
ygrep
. No importa que sean nombres de archivo, solo son texto.\ls | grep Cases | xargs less
le permite examinar los archivos cuyos nombres son producidos por la primera parte del comando.xargs
toma una lista de nombres de archivo como entrada y un comando en su línea de comando, y ejecuta el comando con los nombres de archivo en su línea de comando.Al considerar el uso
xargs
, tenga en cuenta que se espera de entrada con formato de una manera extraña: por espacios en blanco delimitado, con\
,'
y la"
utiliza para citar (de una manera inusual, porque\
no es cotizaciones en el interior especiales). Solo usexargs
si sus nombres de archivo no contienen espacios en blanco o\'"
.fuente
xargs
tiene la-0, --null
opción de solucionar el problema de los espacios (es muy probable que lo haya aprendido de usted :), por lo que supongo que se refiere a unaxarg
llamada sin opciones , pero me desconcierta su referencia a las citas. ¿Tienes un enlace o un ejemplo al respecto? .. (ps.| xargs less
es un práctico "truco" +1 .. gracias ..En su ejemplo, no necesita usar
xargs
nada, yafind
que hará exactamente y con seguridad lo que desea hacer.Exactamente lo que quieres usar
find
es:En este ejemplo
-maxdepth 1
, solo busca en el directorio actual, no descienda a ningún subdirectorio; de forma predeterminada, find buscará en todos los subdirectorios (que a menudo es lo que desea) a menos que lo restrinja con maxdepth. El{}
es el nombre del archivo que será sustituido en su lugar y+
es uno de los dos marcadores de fin de comando, el otro es;
. La diferencia entre ellos es que;
significa ejecutar el comando en cada archivo de uno en uno, mientras que+
significa ejecutar el comando en todos los archivos a la vez. Tenga en cuenta, sin embargo, que su cáscara es probable que tratar de interpretar;
en sí, por lo que tendrá que escapar de ella, ya sea con\;
o';'
. Sí,find
tiene una serie de pequeñas molestias como esta, pero su poder lo compensa con creces.Ambos
find
yxargs
son difíciles de aprender al principio. Para ayudarlo a aprender,xargs
intente usar la opción-p
o--interactive
que le mostrará el comando que está a punto de ejecutar y le preguntará si desea ejecutarlo o no.De manera similar
find
, puede usar-ok
en lugar de-exec
para preguntarle si desea ejecutar el comando o no.Sin embargo, hay momentos en los
find
que no podrás hacer todo lo que quieras y ahí es dondexargs
entra. El-exec
comando solo aceptará una instancia de{}
aparición, por lo que si recibes un error,find -type f -exec cp {} {}.bak \;
puedes hacerlo así. :find -type f -print0 | xargs -0 -l1 -IX cp X X.bak
Puede obtener más información sobre los comandos de ejecución en el manual de GNU Findutils .
Además, mencioné que con
find
seguridad hace lo que desea porque cuando se trata de archivos, encontrará espacios y otros caracteres que causarán problemas axargs
menos que use la opción-0
o--null
junto con algo que genere elementos de entrada terminados por un carácter nulo. de espacios en blanco.fuente
'
o"
pueden ser problemáticos, mientrasfind
que manejarán esos casos sin problemas.xargs
(junto confind
,sort
,du
,uniq
,perl
y algunos otros) acepta un modificador de línea de comandos para decir "STDIN tiene una lista de archivos, separadas por un NUL (0x00) de bytes". Esto facilita el manejo de nombres de archivos con espacios y otros personajes divertidos en ellos. Los nombres de archivo no contienen NUL.fuente