Respuestas:
Bueno, el caso genérico que funciona con cualquier comando que escriba en stdout es usar xargs
, lo que le permitirá adjuntar cualquier número de argumentos de línea de comando al final de un comando:
$ find … | xargs grep 'search'
O para incrustar el comando en su grep
línea con backticks o $()
, que ejecutará el comando y sustituirá su salida:
$ grep 'search' $(find …)
Tenga en cuenta que estos comandos no funcionan si los nombres de los archivos contienen espacios en blanco u otros "caracteres extraños" ( \'"
para xargs, \[*?
para $(find …)
).
Sin embargo, en el caso específico de find
la capacidad de ejecutar un programa en los argumentos dados, está incorporado:
$ find … -exec grep 'search' {} \;
Todo entre -exec
y ;
es el comando a ejecutar; {}
se reemplaza con el nombre de archivo encontrado por find
. Eso ejecutará un separado grep
para cada archivo; dado que grep
puede tomar muchos nombres de archivo y buscarlos todos, puede cambiar a ;
to +
para decirle a find que pase todos los nombres de archivo coincidentes a la grep
vez:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED Si bien -exec +
es muy eficiente, no existe en todas las versiones de find.
$ find … -exec grep 'search' {} \+
forma es mucho más rápida.
Algunas versiones de grep
(por ejemplo, en Linux no integrado o BSD o Mac OS X) tienen una -r
opción para realizar una búsqueda recursiva. En OpenBSD, use -R
(y no hay --exclude
como en el ejemplo a continuación). Esto cubre combinaciones simples de find
con grep
.
Si su implementación no tiene el -R
indicador, o si desea criterios de coincidencia de archivos más sofisticados, puede usar el -exec
primario de find
para que se ejecute grep
. Unos más antiguas find
implementaciones no soportan -exec
... +
; en estos sistemas, use un en ;
lugar del +
(esto llamará grep
una vez por archivo, por lo que será más lento, pero de lo contrario el resultado será el mismo). Tenga en cuenta el /dev/null
truco para hacer grep
que se muestre el nombre del archivo incluso si se llama en un solo archivo (GNU grep y FreeBSD / NetBSD / OSX grep tienen una -H
opción para lograr el mismo efecto).
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
tiene la -H
opción de imprimir siempre el nombre del archivo.