¿Cómo usar grep para buscar texto en TODAS las carpetas?

¿Cómo usar grep para buscar texto en TODAS las carpetas?

Tengo problemas para buscar en TODOS los directorios a la vez con grep. Cuando uso el comando:

find . -name "*.txt" | xargs grep texthere

Simplemente toma una eternidad y luego me da el error "no existe tal archivo o directorio".

¿Por qué sucede esto? ¿No hay nada más fácil que hacerlo grep? ¿O estoy usando el comando incorrecto?

Respuesta1

Si tiene GNU grep, el propio grep admite la opción "-r" para buscar recursivamente, como lo sugiere @Ouroborus.

Si desafortunadamente su grep no admite dicha opción, como en SunOS, puede usar los siguientes comandos:

find . -name "*.txt" -exec grep -n your_pattern {} /dev/null \;

El truco se /dev/nullagrega para garantizar que cada ejecución de grep tenga dos archivos (el archivo que coincide con *.txt y /dev/null) proporcionados, lo que lo obliga a imprimir el nombre de los archivos que se buscan. Y puede agregar -type fla opción de findpara refinar el alcance de find.

Respuesta2

Como enesta respuesta, probablemente estés mejor con:

grep -rnw '/path/to/somewhere/' -e "pattern"

  • -ro -Res recursivo,
  • -nes el número de línea, y
  • -wlos soportes coinciden con toda la palabra.
  • -l(L minúscula) se puede agregar para proporcionar solo el nombre de los archivos coincidentes.

Respuesta3

Si recibe errores sobre los permisos (no dice que los tenga), entonces supongo que se encuentra en el directorio raíz ( /) o en alguna ruta donde no tiene permiso para leer todos los archivos. como en /etco en /var. Pero como usted dice que lleva muchísimo tiempo, me inclino más por la primera suposición (el directorio raíz).

Si quieres buscar absolutamentetodoarchivos en elenterosistema, que lo que estás haciendo es bastante correcto. ÉlvoluntadToma mucho tiempo sin importar lo que hagas. Es simplemente una enorme cantidad de archivos para buscar.

Puede utilizar findpara limitar la cantidad de archivos a ver.

Por el momento tienes

$ find . -name "*.txt" | xargs grep texthere

Como parece que solo le interesan los archivos de texto sin formato, podemos excluir cualquier otro tipo de archivo (ejecutables):

$ find / -type f \! -perm -o=x -name "*.txt" | xargs grep texthere

lo reemplacé .con/ aquí, porque ahí es dondepensarlo eres (corrígeme si me equivoco). También estoy especificando que quieroarchivos(-type f ) que sonno ejecutable( \! -perm -o=x) (es !necesario escapar para que su caparazón no haga cosas raras con él).

Ahora, hay un par de cosas más que podemos hacer. Una es una cuestión de seguridad y la otra puedeposiblementeMejorar un poquito la velocidad.

Algunos nombres de archivos pueden tener espacios u otros caracteres extraños que normalmente no queremos en los nombres de archivos. Para poder pasarlos correctamente entre nosotros findy lo hacemosgrep

$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 grep texthere

Esto ( -print0) significa que cada nombre de archivo estará delimitado por un nulcarácter ( \0) en lugar de un espacio. Y la opción correspondiente para xargsrecibir estos nulnombres de archivos delimitados es -0.

Es porque no estás usando esas dos opciones que creo que obtienes esos errores de "no existe tal archivo o directorio".

Lo de la velocidad es fgrep. Esta es una utilidad que es exactamente equivalente a grep -Fla que debería usar si su cadena de búsqueda es una cadena de texto sin formato sin expresiones regulares.

Entonces, si tiene una cadena de texto sin formato y desea buscarla en cada archivo de todo el sistema:

$ find / -type f \! -perm -o=x -name "*.txt" -print0 | xargs -0 fgrep texthere

Lo del permiso... Obviamente habrá archivos que no podrás leer. Puede ejecutar findy fgrepanteponerles sudo:

$ sudo find ... | xargs -0 sudo fgrep texthere

O podría intentar crear otra -permbandera find(y también hacer que ignore los directorios a los que no puede ingresar), pero eso consumiría demasiado tiempo y resultaría en una línea de comando ridículamente larga, así que no haré eso aquí.

O podría simplemente sudo -sobtener un shell raíz y ejecutarlo desde allí... pero generalmente lo desaconsejaría porque la gente tiende a estropear sus sistemas al olvidar que están root.

OTRA SOLUCIÓNSería utilizar el locatecomando para localizar todos los .txtarchivos en todo el sistema. Ellocate comando no busca en la jerarquía de archivos sino que utiliza una base de datos (que generalmente se actualiza diariamente, por lo que notodolos archivos pueden estar allí). La base de datos sólo contiene archivos en directorios accesibles para todos los usuarios, por lo que si ha eliminado los permisos de lectura en sus propios directorios, sus archivos no estarán allí.

Entonces, reemplazando el findcomando anterior con el locatecasi equivalente:

$ locate '*.txt' -0 | xargs -0 fgrep texthere

La -0opción (o --nullen algunos sistemas) corresponde a la --print0opción de find.

información relacionada