Saltar al contenido

¿Qué hace “xargs grep”?

Solución:

$ find . -name '*.c' | grep 'stdlib.h'

Esto canaliza la salida (stdout) * de find a (stdin de) * grep 'stdlib.h' como texto (es decir, los nombres de archivo se tratan como texto). grep hace lo habitual y encuentra las líneas coincidentes en este texto (cualquier nombre de archivo que contenga el patrón). El contenido de los archivos nunca se lee.

$ find . -name '*.c' | xargs grep 'stdlib.h'

Esto construye un mando grep 'stdlib.h' a lo que cada resultado de find es un argumento, por lo que buscará coincidencias dentro cada archivo encontrado por find (xargs se puede pensar en convertir su stdin en argumentos para los comandos dados) *

Usar -type f en su comando de búsqueda, o obtendrá errores de grep para buscar directorios. Además, si los nombres de archivo tienen espacios, xargs arruinará mucho, así que use el separador nulo agregando -print0 y xargs -0 para obtener resultados más fiables:

find . -type f -name '*.c' -print0 | xargs -0 grep 'stdlib.h'

* agregó estos puntos explicativos adicionales como se sugiere en el comentario de @cat

xargs toma su entrada estándar y la convierte en argumentos de línea de comando.

find . -name '*.c' | xargs grep 'stdlib.h' es muy similar a

grep 'stdlib.h' $(find . -name '*.c')  # UNSAFE, DON'T USE

Y dará los mismos resultados siempre que la lista de nombres de archivo no sea demasiado larga para una sola línea de comando. (Linux admite megabytes de texto en una sola línea de comando, por lo que normalmente no necesita xargs).


Pero ambos apestan, porque se rompen si sus nombres de archivo contienen espacios. En lugar de, find -print0 | xargs -0 funciona, pero también lo hace

find . -name '*.c' -exec grep 'stdlib.h' {} +

Eso nunca canaliza los nombres de archivo a ninguna parte: find los agrupa en una gran línea de comando y ejecuta grep directamente.

; en lugar de + ejecuta grep por separado para cada archivo, que es mucho más lento. No hagas eso. Pero + es una extensión GNU, por lo que necesita xargs para hacer esto de manera eficiente si no puede asumir que GNU find.


Si dejas fuera xargs, find | grep ¿Su patrón coincide con la lista de nombres de archivo que find huellas dactilares.

Entonces, en ese punto, es mejor que hagas find -name stdlib.h. Por supuesto, con -name '*.c' -name stdlib.h, no obtendrá ningún resultado porque esos patrones no pueden coincidir, y el comportamiento predeterminado de find es Y las reglas juntas.

Sustituir less en cualquier punto del proceso para ver qué salida produce cualquier parte de la canalización.


Para leer más: http://mywiki.wooledge.org/BashFAQ tiene algunas cosas geniales.

En general, xargs se utiliza para los casos en los que canalizaría (con el símbolo |) algo de un comando a otro (Command1 | Command2), pero la salida del primer comando no se recibe correctamente como entrada del segundo comando.

Esto suele suceder cuando el segundo comando no maneja la entrada de datos a través de Standard In (stdin) correctamente (por ejemplo: varias líneas como entrada, la forma en que se configuran las líneas, los caracteres utilizados como entrada, varios parámetros como entrada, el tipo de datos recibido como entrada, etc.). Para darle un ejemplo rápido, pruebe lo siguiente:

Ejemplo 1:

ls | echo – Esto no hará nada desde echo no sabe cómo manejar la entrada que está recibiendo. Ahora en este caso si usamos xargs procesará la entrada de una manera que pueda ser manejada correctamente por echo (por ejemplo: como una sola línea de información)

ls | xargs echo – Esto generará toda la información de ls en una sola línea

Ejemplo 2:

Digamos que tengo varios archivos goLang dentro de una carpeta llamada go. Los buscaría con algo como esto:

find go -name *.go -type f | echo – Pero si el símbolo de la tubería allí y el echo al final, no funcionaría.

find go -name *.go -type f | xargs echo – Aquí funcionaría gracias a xargs pero si quisiera cada respuesta del find comando en una sola línea, haría lo siguiente:

find go -name *.go -type f | xargs -0 echo – En este caso, la misma salida de find sería mostrado por echo.

Comandos como cp, echo, rm, less y otros que necesitan una mejor manera de manejar la entrada obtienen un beneficio cuando se usan con xargs.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *