GNU/Linux >> Tutoriales Linux >  >> Linux

Grep recursivo Vs Find / -type F -exec Grep {}; ¿Cuál es más eficiente/más rápido?

¿Qué es más eficiente para encontrar qué archivos en un sistema de archivos completo contienen una cadena:grep recursivo o buscar con grep en una declaración exec? Supongo que encontrar sería más eficiente porque al menos puede filtrar si conoce la extensión del archivo o una expresión regular que coincida con el nombre del archivo, pero cuando solo sabe -type f ¿cual es mejor? GNUgrep 2.6.3; encontrar (GNU findutils) 4.4.2

Ejemplo:

grep -r -i 'the brown dog' /

find / -type f -exec grep -i 'the brown dog' {} ;

Respuesta aceptada:

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 en / (pero aún mire dentro de los archivos y directorios ocultos dentro de ellos).

Suponiendo que quisiste decir:

grep -r -i 'the brown dog' /

Algunas cosas a tener en cuenta:

  • No todos grep las implementaciones admiten -r . Y entre los que lo hacen, los comportamientos difieren:algunos siguen enlaces simbólicos a directorios cuando recorren el árbol de directorios (lo que significa que puede terminar buscando varias veces en el mismo archivo o incluso ejecutar bucles infinitos), algunos no lo harán. Algunos buscarán dentro de los archivos del dispositivo (y llevará bastante tiempo en /dev/zero por ejemplo) o tuberías o archivos binarios..., algunos no lo harán.
  • Es eficiente como grep comienza a buscar dentro de los archivos tan pronto como los descubre. Pero mientras busca en un archivo, ya no busca más archivos para buscar (lo que probablemente sea mejor 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 un grep por archivo. ; solo debe usarse para comandos que aceptan solo un argumento. Además aquí, porque grep mira solo en un archivo, no imprimirá el nombre del archivo, por lo que no sabrá dónde están las coincidencias.

No está buscando dentro de los archivos del dispositivo, canalizaciones, enlaces simbólicos..., no está siguiendo los enlaces simbólicos, pero todavía está buscando potencialmente dentro de cosas como /proc/mem .

find / -type f -exec grep -i 'the brown dog' {} +

sería mucho mejor porque tan pocos grep se ejecutarían los comandos posibles. Obtendrá 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 find ha encontrado suficientes archivos para masticar, por lo que habrá un retraso inicial. Y find no seguirá buscando más archivos hasta el anterior grep ha regresado. Asignar y pasar la lista de archivos grandes tiene algún impacto (probablemente insignificante), por lo que, en general, probablemente será menos eficiente que un grep -r que no sigue el enlace simbólico ni mira dentro de los dispositivos.

Relacionado:¿Cómo funcionan ${0##*/} y ${0%/*}?

Con herramientas GNU:

find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'

Como arriba, como pocos grep se ejecutarán todas las instancias posibles, pero find continuará buscando más archivos mientras el primer grep la invocación está mirando dentro del primer lote. Sin embargo, eso puede o no ser una ventaja. Por ejemplo, con datos almacenados en discos duros rotativos, find y grep acceder a los datos almacenados en diferentes ubicaciones en el disco ralentizará el rendimiento del disco al hacer que la cabeza 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 varios simultáneos grep las invocaciones también podrían mejorar las cosas. Todavía con herramientas GNU en almacenamiento RAID1 con 3 discos,

find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'

podría aumentar significativamente el rendimiento. Tenga en cuenta, sin embargo, que el segundo grep solo se iniciará una vez que se hayan encontrado suficientes archivos para llenar el primer grep dominio. Puede agregar un -n opción a xargs para que eso suceda antes (y pase menos archivos por grep invocación).

También tenga en cuenta que si está redirigiendo xargs salida a cualquier cosa que no sea un dispositivo terminal, entonces greps s comenzarán a almacenar en búfer su salida, lo que significa que la salida de esos grep s probablemente se intercalarán incorrectamente. Tendrías que usar stdbuf -oL (donde esté disponible, como en GNU o FreeBSD) en ellos para evitar eso (aún puede tener problemas con líneas muy largas (generalmente> 4KiB)) o haga que cada uno escriba su salida en un archivo separado y concatene todo al final.

Aquí, la cadena que está buscando está fija (no es una expresión regular), por lo que usar -F opción podría marcar la diferencia (poco probable como grep las implementaciones ya saben cómo optimizar eso).

Otra cosa que podría marcar una gran diferencia es fijar la configuración regional en C si se encuentra 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 de /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 elimine las rutas 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 {} +

Linux
  1. ¿Obteniendo la opción -exec en Find To Work?

  2. ¿Imprimir el nombre de archivo junto con los resultados de Grep en Find -exec?

  3. ¿Salir de Find si falla un -exec?

  4. ¿Cómo encontrar múltiples cadenas en archivos?

  5. bash buscar directorios

Comando Grep en Linux (Buscar texto en archivos)

Cómo encontrar una cadena en un archivo en Linux

Encuentra texto en archivos en Linux usando grep

grep recursivo:excluir directorios específicos

Encontrar un directorio en una terminal de Linux

¿Qué es más eficiente, la compresión tar o zip? ¿Cuál es la diferencia entre tar y zip?