¿Cómo buscar texto en todo el sistema de archivos?

53

Suponiendo que se debe usar la herramienta grep, me gustaría buscar la cadena de texto "800x600" en todo el sistema de archivos.

Lo intenté:

grep -r 800x600 /

Pero no funciona.

Lo que creo que mi comando debería hacer es grep recursivamente a través de todos los archivos / carpetas en la raíz para el texto "800x600" y enumerar los resultados de la búsqueda.

¿Qué estoy haciendo mal?

Level1Coder
fuente
2
¿Y por "no funciona" quieres decir exactamente qué? ¿No imprime ningún resultado, se cuelga o imprime muchos Permission deniederrores? ¿Lo ejecutaste como root o como un usuario normal?
alex
Estoy recibiendo algo de tracción, en primer lugar, estaba en mi directorio de inicio de usuario tratando de ejecutar el comando. Así que ahora tengo cd / out para rootear. Luego probé el mismo comando que el anterior y recibo muchos errores de Permiso denegado. Ok, ahora intento sudo grep -r 800x600 / y luego obtengo un / proc / sysrq-trigger: Error de entrada / salida
Level1Coder
Hmm, no sé por qué no funcionaría. Puede ignorar los errores de acceso haciendo grep -r 800x600 / 2>/dev/null. También puedes intentar ejecutarlo como root.
Totor

Respuestas:

64

Normalmente uso este estilo de comando para ejecutar grepvarios archivos:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

Lo que esto realmente hace es hacer una lista de cada archivo en el sistema, y ​​luego para cada archivo, ejecutar grepcon los argumentos dados y el nombre de cada archivo.

El -xdevargumento dice encontrar que debe ignorar otros sistemas de archivos; esto es bueno para evitar sistemas de archivos especiales como /proc. Sin embargo, también ignorará los sistemas de archivos normales, por lo que si, por ejemplo, su carpeta / home está en una partición diferente, no se buscará, debería decir find / /home -xdev ....

-type fsignifica buscar solo archivos, por lo que se ignoran los directorios, dispositivos y otros archivos especiales (aún se repetirá en los directorios y se ejecutará grepen los archivos internos; simplemente no se ejecutará grepen el directorio en sí, lo que no funcionaría de todos modos). Y la -Hopción greple dice que siempre imprima el nombre del archivo en su salida.

findacepta todo tipo de opciones para filtrar la lista de archivos. Por ejemplo, -name '*.txt'procesa solo archivos que terminan en .txt. -size -2Msignifica archivos que son más pequeños que 2 megabytes. -mtime -5significa archivos modificados en los últimos cinco días. Une estos con -a for y y -o for or , y usa '('paréntesis ')'para agrupar expresiones (entre comillas para evitar que el shell las interprete). Así por ejemplo:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Echa un vistazo man findpara ver la lista completa de posibles filtros.

Richard Downer
fuente
2
Tenga en cuenta que -xdevexcluirá todos los demás sistemas de archivos, no solo los especiales. (por ejemplo, si ha /homemontado como una partición separada, no se buscará).
cjm
Traté de ejecutar cada uno pero ambos devuelven un error -find: paths must precede expression: /
Level1Coder
1
Nota: Cuando no se requieren expresiones regulares, 'fgrep' es significativamente más rápido que 'grep', lo que hará una gran diferencia si está buscando un árbol grande.
Nathan Kidd
1
Puede evitar pasar xargscon tal vez una mejor eficiencia al hacerlo find / -xdev -type f -exec grep -H '800x600' +.
Totor
3
No, el +signo al final del findcomando en realidad hace lo mismo que xargs: genera un grepproceso con varios argumentos.
Totor
14

Normalmente no querrás buscar TODO en el sistema. Linux utiliza nodos de archivo para todo, por lo que algunos "archivos" no son cosas que desea buscar. Por ejemplo, /dev/sdaes el dispositivo de bloque físico para su primer disco duro. Probablemente desee buscar en los sistemas de archivos montados, no en el dispositivo de disco sin formato. También existe la /dev/randomque escupe datos aleatorios cada vez que los lee. Buscar eso no tiene mucho sentido. El /procsistema de archivos también es problemático en su caso.

Recomendaría una de dos cosas.

  1. No busque en la raíz, solo busque los lugares que podrían ser útiles. Buscar /homeo /usro /etcseparadamente. La información que está buscando es probable que sea de un tipo específico, por lo que es probable que esté en una carpeta específica de todos modos. Los ajustes de configuración deben estar en /etc. Sus archivos de datos personales deben estar en /home. Limitar la búsqueda a un área importante como esta reducirá en gran medida sus problemas con greps recursivos.

  2. Excluya el uso de áreas problemáticas --exclude-diry un conjunto de cosas que sabe que no necesita de esta manera:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Por último, no es raro encontrarse con algunos errores de "permiso denegado" cuando se hace una gran grep recursiva. En el curso normal de uso, hay archivos que su usuario no podrá leer. Siempre que estos sean solo algunos archivos extraños y no cosas como el dispositivo sin formato para sus discos duros o todo el sistema de archivos de proceso, está bien simplemente ignorar los errores. De hecho, puede hacer esto en la línea de comando enviando todos los errores a nunca nunca aterrizar:

grep -r search_string /path 2> /dev/null
Caleb
fuente
3
-Ipara excluir binario
Rahul Patil
2

Por simplicidad, sugeriría ack-grep . El enlace muestra muchos casos cuando ack-grepes una mejor opción.

Para usar es, después de la instalación:

ack-grep pattern /
bbaja42
fuente
Gracias por recomendar esto, pero ejecuté esto y realmente no me dio los resultados de búsqueda que esperaba. Parece que tendré que ajustar muchas configuraciones para obtener lo que quiero. A partir de ahora, la respuesta de Richard funciona de inmediato. Analizará esto en el futuro, ya que parece útil también.
Level1Coder
1

Otra forma de verlo es de esta manera:

grep -r /* | grep "800x600"
maniat1k
fuente
0

* entonces obtengo un / proc / sysrq-trigger: error de entrada / salida

Su comando está funcionando, está recibiendo este error porque está tratando de escanear procesos en ejecución en busca de una cadena.

Recomiendo excluir directorios del sistema con

grep -exclude-dir = {proc, sys} "800x600" /

Koffee
fuente
-3

simplemente correcto

grep -r "800x600" /

-Lo que está mal en su comando actual son las comillas, "". Siempre ponga el argumento de cadena grepentre comillas.

Amita
fuente
3
Este no es el problema aquí. No necesita comillas al dar este tipo particular de argumento a grep. Pruébalo y verás. Coloque la cadena "800x600" en un archivo y luego grep 800x600 fileverá que funciona bien. El OP obviamente tiene otro problema.
slm