¿Cómo encuentro todos los archivos que contienen texto específico en Linux?


5259

Estoy tratando de encontrar una manera de escanear todo mi sistema Linux para todos los archivos que contienen una cadena de texto específica. Solo para aclarar, estoy buscando texto dentro del archivo, no en el nombre del archivo.

Cuando estaba buscando cómo hacer esto, me encontré con esta solución dos veces:

find / -type f -exec grep -H 'text-to-find-here' {} \;

Sin embargo, no funciona. Parece mostrar todos los archivos del sistema.

¿Está esto cerca de la forma correcta de hacerlo? Si no, ¿cómo debería? Esta capacidad de encontrar cadenas de texto en archivos sería extraordinariamente útil para algunos proyectos de programación que estoy haciendo.


21
recuerde que grep interpretará cualquiera .como un comodín de un solo carácter, entre otros. Mi consejo es usar siempre fgrep o egrep.
Walter Tross

10
de todos modos, ya casi estabas allí! Simplemente reemplace -Hcon -l(y tal vez grepcon fgrep). Para excluir archivos con ciertos patrones de nombres que usaría findde una manera más avanzada. Sin embargo, vale la pena aprender a usar find. Justo man find.
Walter Tross

66
find … -exec <cmd> +es más fácil de escribir y más rápido que find … -exec <cmd> \;. Funciona solo si <cmd>acepta cualquier número de argumentos de nombre de archivo. El ahorro en el tiempo de ejecución es especialmente grande si <cmd>se inicia lentamente, como los scripts de Python o Ruby.
hagello

Para buscar de forma no recursiva en una ruta determinada, el comando es `grep --include = *. Txt -snw" pattern "thepath / *.
Stéphane Laurent

@ StéphaneLaurent Creo que lo estás complicando demasiado. Solo digrep "pattern" path/*.txt
fedorqui 'así que deja de dañar' el

Respuestas:


9523

Haz lo siguiente:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -ro -Res recursivo,
  • -n es el número de línea y
  • -w significa coincidir con toda la palabra.
  • -l (L minúscula) se puede agregar solo para dar el nombre de archivo de los archivos coincidentes.

Junto con estos, --exclude, --include, --exclude-dirbanderas podrían ser utilizados para una búsqueda eficiente:

  • Esto solo buscará en aquellos archivos que tengan extensiones .c o .h:

    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
    
  • Esto excluirá la búsqueda de todos los archivos que terminen con la extensión .o:

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"
    
  • Para directorios es posible excluir un directorio (s) particular a través del --exclude-dirparámetro. Por ejemplo, esto excluirá los directorios dir1 /, dir2 / y todos coincidirán con * .dst /:

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
    

Esto funciona muy bien para mí, lograr casi el mismo propósito que el tuyo.

Para más opciones consultar man grep.


74
use --exclude. como "grep -rnw --exclude = *. o 'directorio' -e" patrón "
rakib_

98
Vale la pena señalar: parece que la ropción es perezosa (atraviesa primero la profundidad, que se detiene después del primer directorio), mientras que Res codiciosa (atravesará todo el árbol correctamente).
Eliran Malka

55
grep -rnw "Cadena que estaba buscando" hizo lo que necesitaba. ¡Gracias!
ViliusK

33
Nota (especialmente para los novatos): las comillas en el comando anterior son importantes.
madD7

69
@Eliran Malka Ren ratravesará los directorios correctamente, pero Rseguirá enlaces simbólicos.
bzeaman

1499

Puedes usar grep -ilR:

grep -Ril "text-to-find-here" /
  • i significa caso de ignorar (opcional en su caso).
  • R significa recursivo.
  • l significa "mostrar el nombre del archivo, no el resultado en sí".
  • / significa comenzar desde la raíz de su máquina.

85
Según mi experiencia, -iesto hace que se ralentice mucho, así que no lo use si no es necesario. Pruébelo en un determinado directorio y luego generalice. Debe completarse en pocos minutos. Creo que una expresión regular lo haría más lento. Pero mis comentarios se basan en suposiciones, le sugiero que lo pruebe timeal frente de la línea.
Fedorqui 'así que deja de dañar'

44
Sí, /*significa eso. De todos modos, acabo de probarlo y noté que simplemente /funciona.
fedorqui 'así que deja de dañar'

10
Si no está buscando usando una expresión regular, puede usar fgrep en lugar de grep en la mayoría de los sistemas.
markle976

8
Sí @ markle976, de hecho, a partir de grep: fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings.
Fedorqui 'así que deja de dañar'

17
Puede reemplazar / con ruta al directorio grep -Ril "text-to-find-here" ~/sites/o uso. para el directorio actualgrep -Ril "text-to-find-here" .
Negro

329

Puedes usar ack . Es como grep para el código fuente. Puede escanear todo su sistema de archivos con él.

Solo haz:

ack 'text-to-find-here'

En tu directorio raíz.

También puede usar expresiones regulares , especificar el tipo de archivo, etc.


ACTUALIZAR

Acabo de descubrir The Silver Searcher , que es como un ack pero 3-5 veces más rápido que él e incluso ignora los patrones de un .gitignorearchivo.


57
Muy útil, simple y rápido. Advertencia: "En las distribuciones derivadas de Debian, ack está empaquetado como" ack-grep "porque" ack "ya existía" (de beyondgrep.com/install ). Puede terminar ejecutando un convertidor de código Kanji en esos Linux ...
Jose_GD

11
ack o ack-grep tiene buenos reflejos, pero encontrar + grep cuando se usa correctamente es mucho mejor en rendimiento
Sławomir Lenart

14
Tenga en cuenta que ripgrep es más rápido que cualquier otra cosa mencionada aquí, incluyendo The Silver Searcher y plain 'ol grep. Vea esta publicación de blog como prueba.
Radon Rosborough

194

Puedes usar:

grep -r "string to be searched"  /path/to/dir

El rrepresenta recursiva y por lo buscará en la ruta especificada y sus subdirectorios. Esto le dirá el nombre del archivo, así como imprimirá la línea en el archivo donde aparece la cadena.

O un comando similar al que está intentando (ejemplo:) para buscar en todos los archivos javascript (* .js):

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

Esto imprimirá las líneas en los archivos donde aparece el texto, pero no imprime el nombre del archivo.

Además de este comando, también podemos escribir esto: grep -rn "Cadena para buscar" / ruta / a / directorio / o / archivo -r: búsqueda recursiva n: se mostrará el número de línea para las coincidencias


1
Gracias por la versión de búsqueda. Mi versión grep (busybox para NAS) no tiene la opción -r, ¡realmente necesitaba otra solución!
jc

3
¡Gracias por la versión 'encontrar'! Es muy importante poder filtrar por ' .js' o ' .txt', etc. Nadie quiere pasar horas esperando que grep termine de buscar todos los videos de varios gigabytes de las últimas vacaciones familiares, incluso si el comando es Más fácil de escribir.
mightypile

grep mejor que la versión aceptada, porque no aceptó buscar la mitad de las palabras
waza123

114

Puedes usar esto:

grep -inr "Text" folder/to/be/searched/

12
más fácil, detallado, recursivo y sin distinción entre mayúsculas y minúsculas. Pulgares hacia arriba.
Francesco Casula

si agrega -A3 es aún mejor
albanx

73

Lista de nombres de archivo que contienen un texto dado

En primer lugar, creo que has usado en -Hlugar de -l. También puede intentar agregar el texto entre comillas seguido de {} \.

find / -type f -exec grep -l "text-to-find-here" {} \; 

Ejemplo

Supongamos que está buscando archivos que contengan el texto específico "Licencia de Apache" dentro de su directorio. Mostrará resultados algo similares a los siguientes (la salida será diferente según el contenido de su directorio).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Eliminar mayúsculas y minúsculas

Incluso si no utiliza el caso como "texto" frente a "TEXTO", puede usar el -iinterruptor para ignorar el caso. Puedes leer más detalles aquí .

Espero que esto te ayude.


2
Que es lo que hace este comando: findpasará todas las rutas que encuentre al comando grep -l "text-to-find-here" <file found>". Puede añadir restricciones al nombre del archivo, por ejemplo, find / -iname "*.txt"para buscar sólo en los archivos que finaliza en nombre.txt
Mene

1
@ Auxiliar: incluyó una salida de muestra para evitar cualquier confusión para los lectores.
lkamal

2
@Mene Es un estado realmente triste que el comentario de Auxiliary tenga más votos que el tuyo ... incluso si su comentario es de 2014 y el tuyo es 2017, su comentario tiene 6 cuando debería tener exactamente 0 y el tuyo solo tenía uno (ahora dos) isn Es algo que me gustaría creer.
Pryftan

@Mene Dicho esto -inameno distingue entre mayúsculas y minúsculas, lo que significa que también encontraría archivos .TXT, por ejemplo, así como TxT y TXt, etc.
Pryftan

66

grep( GNU o BSD )

Puede usar la grepherramienta para buscar recursivamente la carpeta actual, como:

grep -r "class foo" .

Nota: -r- Recursivamente busca subdirectorios.

También puede usar la sintaxis global para buscar dentro de archivos específicos como:

grep "class foo" **/*.c

Nota: Al usar la opción global ( **), escanea todos los archivos de forma recursiva con una extensión o patrón específico. Para habilitar esta sintaxis, ejecute: shopt -s globstar. También puede usarlo **/*.*para todos los archivos (excepto los ocultos y sin extensión) o cualquier otro patrón.

Si tiene el error de que su argumento es demasiado largo, considere reducir su búsqueda, o use una findsintaxis en su lugar como:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Alternativamente uso ripgrep.

ripgrep

Si está trabajando en proyectos más grandes o archivos grandes, debe usarlos ripgrep, como:

rg "class foo" .

Consulte los documentos, los pasos de instalación o el código fuente en la página del proyecto GitHub .

Es mucho más rápido que cualquier otra herramienta como GNU / BSD grep , ucg, ag, sift, ack,pt o similares, ya que se construye en la parte superior del motor de expresiones regulares de Rust que utiliza autómatas finitos, SIMD y optimizaciones literales agresivas para que la búsqueda sea muy rápido.

Admite ignorar patrones especificados en .gitignore archivos, por lo que una sola ruta de archivo se puede comparar con múltiples patrones globales simultáneamente.


Puede usar los parámetros comunes como:

  • -i - Búsqueda insensible.
  • -I - Ignorar los archivos binarios.
  • -w - Buscar las palabras completas (en oposición a la coincidencia parcial de palabras).
  • -n - Muestra la línea de tu partido.
  • -C/ --context(por ejemplo-C5 . ): aumenta el contexto para que vea el código circundante.
  • --color=auto - Marcar el texto correspondiente.
  • -H - Muestra el nombre del archivo donde se encuentra el texto.
  • -c- Muestra el recuento de líneas coincidentes. Se puede combinar con -H.

1
También encuentro útil el globbing extendido. Pero tenga en cuenta que si hay una gran cantidad de archivos, puede obtener el error "Lista de argumentos demasiado larga". (El globbing simple también es propenso a este tipo de error).
Yoory N.

2
Para inhalar un sistema de archivos completo, rg será mucho menos doloroso que casi cualquier otra herramienta.
lk

55

Si grepno admite la búsqueda recursiva, puede combinarla findcon xargs:

find / -type f | xargs grep 'text-to-find-here'

Esto me resulta más fácil de recordar que el formato find -exec.

Esto generará el nombre del archivo y el contenido de la línea coincidente, p. Ej.

/home/rob/file:text-to-find-here

Indicadores opcionales que puede agregar a grep:

  • -i - búsqueda sin distinción entre mayúsculas y minúsculas
  • -l - solo muestra el nombre del archivo donde se encontró la coincidencia
  • -h - solo muestra la línea que coincide (no el nombre del archivo)

3
Esto es equivalente a grep 'text-to-find-here'sin nombre de archivo si findno encuentra nada. ¡Esto se bloqueará y esperará la entrada del usuario! Agregar --no-run-if-emptycomo una opción para xargs.
hagello

3
Esta combinación de find y xargs no funciona según lo previsto si los nombres de archivo o directorio contienen espacios (caracteres que xargs interpreta como separadores). Uso find … -exec grep … +. Si insiste en usar find junto con xargs, use -print0y -0.
hagello

43
grep -insr "pattern" *
  • i: Ignora las distinciones entre mayúsculas y minúsculas tanto en el PATRÓN como en los archivos de entrada.
  • n: Prefije cada línea de salida con el número de línea basado en 1 dentro de su archivo de entrada.
  • s: Suprime mensajes de error sobre archivos inexistentes o ilegibles.
  • r: Lea todos los archivos de cada directorio de forma recursiva.

3
¿Puedes explicar cómo tu respuesta mejora sobre las otras respuestas, o cómo es lo suficientemente diferente de ellas?
Amos M. Carpenter

no es muy complejo de recordar, cubrirá todos los patrones (mayúsculas y minúsculas -> desactivado, incluye nombres de archivo y número de línea y buscará recursivamente, etc.) y usar "*" al final buscará en todos los directorios (no es necesario especificar ninguno ruta o nombre del directorio).
enfinet

Lo siento, debería haber sido más claro: sería genial si pudieras incluir esa explicación en tu respuesta. En su forma actual, especialmente con tantas otras respuestas similares ya, es difícil de ver desde una respuesta tan corta cuál es el beneficio de tratar que habría terminado la respuesta aceptada o uno de los upvoted queridos.
Amos M. Carpenter

66
@ AmosM.Carpenter Una cosa que me encanta de esta respuesta es señalar el argumento de supresión, que puede ayudar a filtrar el ruido que no importa para obtener los resultados que realmente queremos. Grep imprime errores como "Función no implementada", "Argumento no válido", "Recurso no disponible", etc., etc. en ciertos "archivos".
leetNightshade

@leetNightshade: Supongo que me diriges tu comentario porque te pedí una explicación sobre la escasa publicación original. Vea la gran revisión de Fabio para que mis comentarios anteriores tengan sentido.
Amos M. Carpenter

39

Hay una nueva utilidad llamada The Silversearcher

sudo apt install silversearcher-ag

Funciona estrechamente con Git y otros VCS. Por lo tanto, no obtendrá nada en un .git u otro directorio.

Simplemente puedes usar

ag "Search query"

¡Y hará la tarea por ti!


35

¿Cómo encuentro todos los archivos que contienen texto específico en Linux? (...)

Encontré esta solución dos veces:

find / -type f -exec grep -H 'text-to-find-here' {} \;


Si usa find like en su ejemplo, agregue mejor -s( --no-messages) a grep, y 2>/dev/nullal final del comando para evitar muchos mensajes de Permiso denegado emitidos por grepy find:

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

find es la herramienta estándar para buscar archivos, combinada con grep cuando se busca texto específico, en plataformas tipo Unix. Elcomando find a menudo se combina con xargs , por cierto.

Existen herramientas más rápidas y fáciles para el mismo propósito: ver más abajo. Mejor pruébelos, siempre que estén disponibles en su plataforma , por supuesto:

Alternativas más rápidas y fáciles

RipGrep : la herramienta de búsqueda más rápida en torno a:

rg 'text-to-find-here' / -l

El buscador de plata :

ag 'text-to-find-here' / -l

ack :

ack 'text-to-find-here' / -l

Nota: También puede agregar 2>/dev/nulla estos comandos para ocultar muchos mensajes de error.


Advertencia : a menos que realmente no pueda evitarlo, ¡no busque desde '/' (el directorio raíz) para evitar una búsqueda larga e ineficiente! Por lo tanto, en los ejemplos anteriores, será mejor que reemplace ' / ' por un nombre de subdirectorio, por ejemplo, "/ home", dependiendo de dónde realmente desea buscar ...


'find es la herramienta estándar para buscar archivos que contienen texto específico en plataformas tipo Unix' me parece bastante ambiguo. Incluso, además de recursivo grep find, no busca directamente el texto en el interior de los archivos. Y tal vez esas herramientas adicionales son útiles para algunos, pero los veteranos y aquellos que están acostumbrados, por ejemplo grep, no les darían ningún tiempo (bueno, ciertamente no lo haré). Sin embargo, no digo que sean inútiles.
Pryftan

"... que contiene texto específico ...": esta parte de la oración no fue precisa (porque no se trata de esta parte de la búsqueda). Editado Gracias.
Bludzee

¡Me alegra ser de ayuda! Lo único más a simple vista es cambiar la carpeta de palabras al directorio, pero sé que es una cruzada mía que nunca ganaré por completo. Aunque no te
rindas

¿Por qué no "directorio" en lugar de "carpeta", sino por qué? ¡Por favor comparte tu "cruzada"!
Bludzee

Estoy diciendo que use el directorio en su lugar! Refiriéndose a: será mejor que reemplace '/' por el nombre de una subcarpeta Y es un motivo favorito mío, especialmente porque incluso Windows solía llamarlo 'directorio'. Ah ... tal vez lo tienes. ¿Por qué? Bueno, porque así se llama. También se llama así a nivel del sistema de archivos. Y míralo de esta manera: ¿alguna vez se llamó (para DOS) fol? No claro que no; fue llamado dir(y creo que todavía lo es). La carpeta es una cosa ideada para (supongo) facilidad de uso, aunque en este caso tal vez sea tonta para usuarios menos 'avanzados'.
Pryftan

29

Tratar:

find . -name "*.txt" | xargs grep -i "text_pattern"

55
Este es realmente un excelente ejemplo de cuándo NO usarlo de xargsesa manera ... considere esto. echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo. El xargsaquí coincide con el archivo INCORRECTO y NO coincide con el archivo deseado. O usa un find .. -print0 | xargs -0 ...pero ese es un uso inútil de una tubería o mejorfind ... -exec grep ... {} +
shalomb

29

Use pwdpara buscar desde cualquier directorio en el que se encuentre, recurriendo hacia abajo

grep -rnw `pwd` -e "pattern"

Actualización Dependiendo de la versión de grep que esté utilizando, puede omitir pwd. En las versiones más recientes .parece ser el caso predeterminado para grep si no se proporciona un directorio así:

grep -rnw -e "pattern"

o

grep -rnw "pattern"

Hará lo mismo que arriba!


3
el uso pwdno es necesario en absoluto, ya que es el predeterminado. grep -rnw "pattern"es suficiente
Fedorqui 'SO deja de dañar'

y de hecho el grep -rnwy similar es como fue respondido hace tres años, no veo cómo esta respuesta está agregando valor.
Fedorqui 'SO deja de dañar'

La respuesta seleccionada no muestra el patrón predeterminado, y 5 personas parecían haberlo encontrado útil
Mahatmanich

¿Qué quieres decir con "patrón predeterminado"? La respuesta aceptada contiene grep -rnw '/path/to/somewhere/' -e "pattern"cuál es lo que tienes aquí. 5 votos después de 2.3 millones de visitas no significa mucho.
fedorqui 'SO deja de dañar'

Estoy de acuerdo :-) lo que me faltaba en la respuesta original es el caso de uso que no tiene que dar una ruta o buscar el directorio actual de forma recursiva que no se refleja en la respuesta aceptada. Por lo tanto, fue una buena experiencia de aprendizaje sobre grep profundizar un poco más.
mahatmanich

19

grep se puede usar incluso si no estamos buscando una cadena.

Simplemente corriendo,

grep -RIl "" .

imprimirá la ruta a todos los archivos de texto, es decir, aquellos que contengan solo caracteres imprimibles.


2
No veo cómo esto es mejor que usar un mero lso find(para el recursivo)
fedorqui 'SO deja de dañar'

17

Aquí están las varias listas de comandos que pueden usarse para buscar archivos.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "word-1|word-2” directory-path

egrep -w -R "word-1|word-2” directory-path

55
¿Qué está agregando esto a las respuestas existentes?
Fedorqui 'SO deja de dañar'

@fedorqui egrepes equivalente grep -Ey significa --extended-regexpque puede encontrar detalles aquí unix.stackexchange.com/a/17951/196072
omerhakanbilici


15
find /path -type f -exec grep -l "string" {} \;

Explicación de comentarios

find es un comando que le permite encontrar archivos y otros objetos como directorios y enlaces en subdirectorios de una ruta determinada. Si no especifica una máscara que los nombres de archivo deben cumplir, enumera todos los objetos de directorio.

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename

15

Tratar:

find / -type f -exec grep -H 'text-to-find-here' {} \;

que buscará en todos los sistemas de archivos, porque / es la carpeta raíz.

Para el uso de la carpeta de inicio:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

Para uso de carpeta actual:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;

Quizás los detalles sobre las diferencias de carpetas son obvios para muchos ... pero también muy útiles para los novatos. +1
nilon

1
¿Qué está agregando esto a las respuestas existentes?
Fedorqui 'SO deja de dañar'

Llámalo mi cruzada pero la palabra es 'directorio'. Esto no es Windows (que solía usar 'directorio' de todos modos, anterior a 9x). Por favor, deja de decir 'carpeta'. En cuanto a su último comando, ni siquiera necesita el '/' solo FYI.
Pryftan

15

Espero que esto sea de ayuda ...

Expandir grepun poco para dar más información en la salida, por ejemplo, para obtener el número de línea en el archivo donde está el texto, se puede hacer de la siguiente manera:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

Y si tiene una idea del tipo de archivo, puede reducir su búsqueda especificando extensiones de tipo de archivo para buscar, en este caso archivos .pasOR .dfm:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Breve explicación de las opciones:

  1. .en el findespecifica del directorio actual.
  2. -name" *.*": Para todos los archivos (-name " *.pas" -o -name " *.dfm"): Sólo los *.pasOR *.dfmarchivos o especificado con-o
  3. -type f especifica que está buscando archivos
  4. -print0y --nullen el otro lado de la |(tubería) están los cruciales, pasando el nombre del archivo de findal grepincrustado en el xargs, permitiendo el paso de nombres de archivo CON espacios en los nombres de archivo, permitiendo que grep trate la ruta y el nombre de archivo como una sola cadena, y no dividirlo en cada espacio.

-name '*.*'no es lo que dices no se recogería en un archivo llamado 'archivo' porque el patrón no equivale a eso (no .ext); *sin embargo (bueno. archivos a un lado). Pero hay otra cosa: si quiere todos los archivos, ¿por qué molestarse en especificar un nombre de archivo en primer lugar? Ningún otro comentario, excepto que es bueno saber que todavía hay personas que no usan la 'carpeta' de terminología de MS (que realmente, después de decirlo lo suficiente, no agregaría pero quería señalar la afirmación ligeramente incorrecta que hizo con nombres de archivo, así como la redundancia / inutilidad en el caso de 'todos').
Pryftan

15

Un simple findpuede ser útil. alias en tu ~/.bashrcarchivo:

alias ffind find / -type f | xargs grep

Inicie una nueva terminal y emita:

ffind 'text-to-find-here'

14

Escribí un script de Python que hace algo similar. Así es como se debe usar este script.

./sniff.py path pattern_to_search [file_pattern]

El primer argumento, pathes el directorio en el que buscaremos de forma recursiva. El segundo argumento, pattern_to_searches una expresión regular que queremos buscar en un archivo. Usamos el formato de expresión regular definido en la biblioteca Python re . En este script, el. también coincide con la nueva línea.

El tercer argumento, file_pattern , es opcional. Esta es otra expresión regular que funciona en un nombre de archivo. Solo se considerarán aquellos archivos que coincidan con esta expresión regular.

Por ejemplo, si quiero buscar archivos de Python con la extensión que pycontiene Pool(seguido de word Adaptor, hago lo siguiente,

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

Y listo, genera la ruta de los archivos coincidentes y el número de línea en el que se encontró la coincidencia. Si se encontró más de una coincidencia, entonces cada número de línea se agregará al nombre del archivo.


14

Si desea usar estrictamente find, use find + grep:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

pasos:

1.Utilice findpara buscar archivos,
2.Entonces ejecutegrep en todos ellos.

Esto puede darle el poder de findbuscar archivos.

  • Úselo -name Patternsi grepsolo desea ciertos archivos:

    find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Puedes jugar con él y usar diferentes opciones findpara mejorar o reducir tu búsqueda de archivos.


¿Cuál es la diferencia? ¿Funcionará con espacios en la ruta del archivo?
Peter Mortensen

13

Utilizar:

grep -c Your_Pattern *

Esto informará cuántas copias de su patrón hay en cada uno de los archivos en el directorio actual.


13

grep es tu buen amigo para lograr esto.

grep -r <text_fo_find> <directory>

Si no le importa el caso del texto para buscar, utilice:

grep -ir <text_to_find> <directory>

En mi caso, parece que busca en todas partes, incluso si especifico el directorio
Pathros

@Pathros Probablemente tenga que ver con la recursividad habilitada y el directorio que especifique. Dicho de otra manera, la recursión cambia las cosas de esa manera.
Pryftan

@Pathros Ah, y si hay alguna -s en la cadena de búsqueda, --primero querrá pasar a grep; eso puede causar efectos secundarios interesantes de lo contrario!
Pryftan

13

Estoy fascinado por lo simple que grep lo hace con 'rl':

grep -rl 'pattern_to_find' /path/where/to/find

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

¡Use '-r' sin 'l' para ver los nombres de los archivos seguidos del texto en el que se encuentra el patrón !

grep -r 'pattern_to_find' /path/where/to/find

Funciona simplemente perfecto ...


Esto también funciona en Git Bash (Windows).
Peter Mortensen

Pero implica que cada archivo debe buscarse (sin filtro en el nombre del archivo o nivel de extensión del archivo, como .txt) ¿O hay una manera de hacer eso?
Peter Mortensen

12

Para buscar la cadena y generar solo esa línea con la cadena de búsqueda:

for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done

p.ej:

for i in $(find /usr/share/applications -type f); \
do grep -i "web browser" "$i"; done

Para mostrar el nombre de archivo que contiene la cadena de búsqueda:

for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

p.ej:

for i in $(find /usr/share/applications -type f); \
do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
fi; done;

1
Solo veo inconvenientes en comparación con el uso find … -exec grep 'str' {} \;(si es que tiene que usarlo find).
phk

1
Esto se rompería horriblemente si alguno de los archivos encontrados por findespacios contenidos ... podría terminar con greppinglos archivos incorrectos y / o faltar los archivos correctos por completo. Solo úselo find ... -exec grep ...si necesita usarlo find... pero en este caso es grep -r ...suficiente.
shalomb

1
¿Cuál es el punto de usar un ciclo sobre los resultados de find para luego grep? Esto se vuelve innecesariamente complicado.
Fedorqui 'SO deja de dañar'

12

Hay un ack herramienta que haría exactamente lo que estás buscando.

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

Puede ignorar la -ibúsqueda sensible a mayúsculas y minúsculas


2
¿Qué está agregando esto a las respuestas existentes? Esto ya se sugirió hace más de tres años.
fedorqui 'SO deja de dañar'

1
@fedorqui 1) sin tuberías! 2) Use expresiones regulares 3) Obtenga números de línea, nombre de archivo con ruta relativa, texto resaltado, etc. útil para editar después de la búsqueda, por ejemplo, "vim + lineno path / file.cpp" lo llevará directamente a la línea sin interés. Consulte el resultado del comando "ack include \ | hpp" que busca las palabras clave "include" o "hpp" en mi carpeta de búsqueda y subcarpetas. Espero que el punto sea claro. Aquí está la salida de muestra (No se pueden mostrar las palabras clave resaltadas con texto simple) process / child.hpp 11: boost / process / child.hpp process / all.hpp 21: #include <boost / process / execute.hpp>
Pal

12

Todas las respuestas anteriores sugieren grep y find. Pero hay otra forma: usar Midnight Commander

Es una utilidad gratuita (30 años, probada por tiempo) que es visual sin ser GUI. Tiene toneladas de funciones, y encontrar archivos es solo una de ellas.


guardabosques estaría en la misma idea
nilon

11

El siguiente comando funcionará bien para este enfoque:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;

2
¿Cuál es el punto de usar findy luego grep -r? Están destinados a lo mismo, por lo que esto es redundante.
fedorqui 'DEJA de dañar'

ohh !! corregido, En realidad encontrar es para ejecutar grep en archivos filtrados y no todos, gracias
Pradeep Goswami

2
Aún así, esto no tiene ningún sentido, puede filtrar con find.
Fedorqui 'SO dejar de dañar'

11

Evite la molestia e instale ack-grep. Elimina muchos problemas de permisos y citas.

apt-get install ack-grep

Luego vaya al directorio que desea buscar y ejecute el siguiente comando

cd /
ack-grep "find my keyword"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.