Estoy usando find
y obteniendo una lista de archivos que quiero grep
pasar. ¿Cómo canalizo esa lista grep
?
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.-exec
, en lugar de elxargs
. Si se utiliza el-exec
enfind
, se creará una sola concha para grep para el contenido. Si usa elxargs
, creará dos shells: uno para elfind
y el otro para elxargs
.$ 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 defind
congrep
.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 defind
para que se ejecutegrep
. Unos más antiguasfind
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 hacergrep
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).fuente
GNU grep
tiene la-H
opción de imprimir siempre el nombre del archivo.