Cuando quiero buscar contenido en un árbol completo, uso
find . -type f -print0 | xargs -0 grep <search_string>
¿Hay una mejor manera de hacer esto en términos de rendimiento o brevedad?
Cuando quiero buscar contenido en un árbol completo, uso
find . -type f -print0 | xargs -0 grep <search_string>
¿Hay una mejor manera de hacer esto en términos de rendimiento o brevedad?
Respuestas:
Verifique si su opción de grep
soporte -r
(para recurse ):
grep -r <search_string> .
--exclude-dir
para abordar el rendimiento y tenemos un ganador!
grep
en las recientes distribuciones de FreeBSD y Linux lo admiten. Y por qué --exclude-dir
? ¿No pediste buscar un árbol entero ?
--exclude-dir
es realmente útil en mi caso de uso (porque partes del subárbol son grandes, pero inútiles) y pregunté sobre el rendimiento ... pero tienes razón, no es necesario.
--exclude-dir
es exclusivo de GNU grep
. (-:
Una respuesta subóptima: en lugar de canalizar la salida de find
en grep
, simplemente podría ejecutar
find . -type f -exec grep 'research' {} '+'
y listo, un comando en lugar de dos!
explicación:
find . -type f
encuentra todos los archivos regulares dentro.
-exec grep 'research'
grep 'investigación'
{}
en nombre de archivo encontrado
'+'
use un comando por todos los nombres de archivo, no una vez por nombre de archivo.
Nb: con ';'
esto hubiera sido una vez por nombre de archivo.
Aparte de eso, si usa eso para procesar el código fuente, puede investigar ack
, que está hecho para buscar bits de código fácilmente.
Editar:
Puedes extender esa investigación un poco. Primero, puede usar el -name ''
interruptor de find
para buscar archivos con un patrón de nomenclatura específico.
Por ejemplo :
solo archivos que corresponden a registros: -name '*.log'
solo archivos que corresponden a encabezados c, pero no puede seguir con mayúsculas o minúsculas para sus extensiones de nombre de archivo: -iname *.c
Nb: como para grep
y ack
, el -i
interruptor significa mayúsculas y minúsculas en este caso.
En ese caso, grep se mostrará sin color y sin números de línea.
Puede cambiar eso con el --color
y los -n
interruptores (números de color y líneas en los archivos, respectivamente).
Al final, puedes tener algo como:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
por ejemplo
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
-name '*.log'
es más rápido.
Si desea recurrir a subdirectorios:
grep -R 'pattern' .
La -R
opción no es una opción estándar, pero es compatible con las grep
implementaciones más comunes .
-r
lugar de -R
omitir enlaces simbólicos cuando se trate de GNU grep
grep
implementaciones actuales de GNU atrapan recursiones, creo. De lo contrario, depende de lo que quiere decir con "árbol".
grep
debería hacer. Si el usuario tiene bucles de enlace simbólico en su estructura de directorio, bueno, ese es el problema del usuario :-)
/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...
(-XI como herramientas que me cuidan (a menos que proporcionen magia extraña que llaman "AI"). (-;
Como se señaló anteriormente -r
o -R
(dependiendo del manejo deseado del enlace simbólico) es una opción rápida.
Sin embargo, -d <action>
puede ser útil a veces.
Lo bueno -d
es el comando de omisión, que silencia el "grep: nombre_directorio: es un directorio" cuando solo quiere escanear el nivel actual.
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
y por supuesto:
$ grep -d recurse foo *
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).
$
La -d skip
opción es REALMENTE útil dentro de otro script para que no tenga que hacerlo 2> /dev/null
. :)
Si se trata de una gran cantidad de archivos, el grep se ejecuta más rápido si poda los archivos que necesita buscar en lugar de agrupar todos los archivos en subcarpetas.
A veces uso este formato:
grep "primary" `find . | grep cpp$`
Encuentra todos los archivos en subcarpetas de .
ese final en cpp
. Luego grep esos archivos para "primario".
Si lo desea, puede seguir canalizando esos resultados en otras llamadas grep:
grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"