No estoy seguro:
grep -r -i 'the brown dog' /*
es realmente lo que quisiste decir. Eso significaría grep recursivamente en todos los archivos y directorios no ocultos /
(pero aún mira dentro de los archivos y directorios ocultos dentro de ellos).
Suponiendo que quisieras decir:
grep -r -i 'the brown dog' /
Algunas cosas a tener en cuenta:
- No todas las
grep
implementaciones son compatibles -r
. Y entre los que lo hacen, los comportamientos difieren: algunos siguen enlaces simbólicos a directorios cuando atraviesan el árbol de directorios (lo que significa que puede terminar buscando varias veces en el mismo archivo o incluso ejecutarse en bucles infinitos), otros no. Algunos buscarán dentro de los archivos del dispositivo (y llevará bastante tiempo, /dev/zero
por ejemplo) o tuberías o archivos binarios ..., otros no.
- Es eficiente ya que
grep
comienza a buscar dentro de los archivos tan pronto como los descubre. Pero mientras se ve en un archivo, ya no busca más archivos para buscar (lo que probablemente sea igual de bueno en la mayoría de los casos)
Tu:
find / -type f -exec grep -i 'the brown dog' {} \;
(eliminado el -r
que no tenía sentido aquí) es terriblemente ineficiente porque está ejecutando uno grep
por archivo. ;
solo debe usarse para comandos que aceptan solo un argumento. Además, aquí, debido a que grep
solo se ve en un archivo, no imprimirá el nombre del archivo, por lo que no sabrá dónde están las coincidencias.
No estás buscando dentro de los archivos del dispositivo, tuberías, enlaces simbólicos ..., no estás siguiendo los enlaces simbólicos, pero aún estás potencialmente buscando cosas como /proc/mem
.
find / -type f -exec grep -i 'the brown dog' {} +
sería mucho mejor porque grep
se ejecutarían la menor cantidad de comandos posible. Obtendría el nombre del archivo a menos que la última ejecución tenga solo un archivo. Para eso es mejor usar:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
o con GNU grep
:
find / -type f -exec grep -Hi 'the brown dog' {} +
Tenga en cuenta que grep
no se iniciará hasta que find
haya encontrado suficientes archivos para masticar, por lo que habrá un retraso inicial. Y find
no continuará buscando más archivos hasta que el anterior grep
haya regresado. La asignación y aprobación de la lista de archivos grandes tiene un impacto (probablemente insignificante), por lo que, en general, será menos eficiente que un grep -r
enlace simbólico o que no mire dentro de los dispositivos.
Con herramientas GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
Como se indicó anteriormente, grep
se ejecutarán la menor cantidad posible de instancias, pero find
continuarán buscando más archivos mientras la primera grep
invocación se encuentra dentro del primer lote. Sin embargo, eso puede o no ser una ventaja. Por ejemplo, con los datos almacenados en discos duros rotativos, find
y el grep
acceso a los datos almacenados en diferentes ubicaciones del disco disminuirá el rendimiento del disco al hacer que el cabezal del disco se mueva constantemente. En una configuración RAID (donde find
y grep
puede acceder a diferentes discos) o en SSD, eso podría marcar una diferencia positiva.
En una configuración RAID, ejecutar varias invocaciones concurrentes grep
también podría mejorar las cosas. Aún con herramientas GNU en almacenamiento RAID1 con 3 discos,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
podría aumentar el rendimiento significativamente. Sin embargo, grep
tenga en cuenta que el segundo solo se iniciará una vez que se hayan encontrado suficientes archivos para completar el primer grep
comando. Puede agregar una -n
opción xargs
para que eso suceda antes (y pasar menos archivos por grep
invocación).
También tenga en cuenta que si está redirigiendo la xargs
salida a cualquier cosa que no sea un dispositivo terminal, entonces los greps
s comenzarán a almacenar en búfer su salida, lo que significa que la salida de esos grep
s probablemente se entrelazará incorrectamente. Tendría que usar stdbuf -oL
(cuando esté disponible, como en GNU o FreeBSD) en ellos para solucionarlo (aún puede tener problemas con líneas muy largas (generalmente> 4KiB)) o hacer que cada uno escriba su salida en un archivo separado y los concatene todo al final.
Aquí, la cadena que está buscando es fija (no es una expresión regular), por lo que usar la -F
opción puede hacer la diferencia (es poco probable ya que las grep
implementaciones ya saben cómo optimizar eso).
Otra cosa que podría marcar una gran diferencia es arreglar la configuración regional en C si está en una configuración regional de varios bytes:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
Para evitar mirar dentro /proc
, /sys
..., use -xdev
y especifique los sistemas de archivos en los que desea buscar:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
O pode los caminos que desea excluir explícitamente:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +