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

Estoy tratando de encontrar una forma 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 en el sistema.

¿Está 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 progtwigción que estoy haciendo.

Haz lo siguiente:

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

Junto con estos, se pueden usar --include , --include , --include --exclude-dir flags para una búsqueda eficiente:

  • Esto solo buscará 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 terminan con la extensión .o:

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

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

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

Para ver más opciones, consulte man grep .

Puedes usar grep -ilR :

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

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 ack pero 3-5 veces más rápido que él e incluso ignora los patrones de un archivo .gitignore .

Puedes usar:

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

El r significa recursivo y, por lo tanto, buscará en la ruta especificada y también en sus subdirectorios. Esto le dirá el nombre del archivo e imprimirá la línea en el archivo donde aparece la cadena.

O un comando similar al que estás 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, podemos escribir esto también: grep -rn “Cadena para buscar” / ruta / a / directorio / o / archivo -r: búsqueda recursiva n: número de línea se mostrará para los partidos

Puedes usar esto:

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

Lista de nombres de archivos que contienen un texto dado

Antes que nada, creo que has usado -H lugar de -l . También puede intentar agregar el texto entre comillas seguido de {} \ .

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

Ejemplo

Digamos que está buscando archivos que contengan texto específico “Apache License” dentro de su directorio. Mostrará resultados algo similares a los de abajo (el resultado 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 la sensibilidad del caso

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

Espero que esto te ayude.

Si su grep no es compatible con la búsqueda recursiva, puede combinar find con xargs :

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

Me parece más fácil de recordar que el formato para find -exec .

Esto generará el nombre de archivo y el contenido de la línea coincidente, por ejemplo

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

Indicadores opcionales que puede querer agregar a grep :

  • -i – búsqueda insensible a 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 de archivo)
 grep -insr "pattern" * 
  • i : Ignora las distinciones de los casos tanto en el PATRÓN como en los archivos de entrada.
  • n : Prefija cada línea de salida con el número de línea 1 en su archivo de entrada.
  • s : suprime mensajes de error sobre archivos inexistentes o ilegibles.
  • r : lee todos los archivos debajo de cada directorio, recursivamente.

grep ( GNU o BSD )

Puede usar la herramienta grep para buscar recursivamente la carpeta actual, como:

 grep -r "class foo" . 

Nota: -r : subdirectorios de búsqueda recursiva.

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

 grep "class foo" **/*.c 

Nota: Al usar la opción globbing ( ** ), escanea todos los archivos recursivamente con una extensión o patrón específico. Para habilitar esta syntax, ejecute: shopt -s globstar . También puede usar **/*.* Para todos los archivos (excluyendo ocultos y sin extensión) o cualquier otro patrón.

Si tiene el error de que su argumento es demasiado largo, considere restringir su búsqueda, o use la syntax de búsqueda en su lugar, como:

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

Alternativamente, use ripgrep .

ripgrep

Si está trabajando en proyectos más grandes o grandes, debería usar ripgrep , como:

 rg "class foo" . 

Verifique 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 similar, ya que está construida sobre el motor regex de Rust que utiliza optimizaciones finitas de autómatas, SIMD y agresivas para hacer búsquedas rápidas .

Es compatible con ignorar patrones especificados en archivos .gitignore , por lo que una sola ruta de archivo puede coincidir contra múltiples patrones globales simultáneamente.


Puede usar los parámetros comunes tales como:

  • -i – Búsqueda insensible.
  • -I – Ignora los archivos binarios.
  • -w – Busca las palabras completas (en oposición al emparejamiento parcial de palabras).
  • -n – Muestra la línea de tu partida.
  • -C / --context (ej. -C5 ) – Incrementa el contexto, para que vea el código circundante.
  • --color=auto – Marque 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 .

Tratar:

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

Use pwd para buscar desde cualquier directorio en el que se encuentre, recursándolo hacia abajo

 grep -rnw `pwd` -e "pattern" 

Actualización Dependiendo de la versión de grep que esté utilizando, puede omitir pwd . En versiones más nuevas . parece ser el caso por defecto para grep si no se da el directorio así:

grep -rnw -e "pattern"

o

grep -rnw "pattern"

hará lo mismo que arriba!

Hay una nueva utilidad llamada The Silversearcher

 sudo apt install silversearcher-ag 

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

Puedes simplemente usar

 ag -ia "Search query" 

¡Y hará la tarea por ti!

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 solo contienen caracteres imprimibles.

Aquí hay una lista de comandos que se pueden usar 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 

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

Me encontré con esta solución dos veces:

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


Si utiliza find como en su ejemplo, mejor agregue -s ( --no-messages ) a grep , y 2>/dev/null al final del comando para evitar muchos permisos de mensajes denegados emitidos por grep y 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 busca texto específico, en plataformas tipo Unix. El comando find a menudo se combina con xargs , por cierto.

Existen herramientas más rápidas y fáciles para el mismo propósito, ver a continuación. Es mejor probarlos, siempre que estén disponibles en su plataforma , por supuesto:

Alternativas más rápidas y fáciles

RipGrep : herramienta de búsqueda más rápida:

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

The Silver Searcher :

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

ack :

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

Nota: También puede agregar 2>/dev/null a 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 desee buscar …

Un find simple puede ser útil. alias en su archivo ~/.bashrc :

 alias ffind find / -type f | xargs grep 

Inicie una nueva terminal y emita:

 ffind 'text-to-find-here' 

Escribí un script de Python que hace algo similar. Así es como uno debería usar esta secuencia de comandos.

 ./sniff.py path pattern_to_search [file_pattern] 

El primer argumento, path , es el directorio en el que buscaremos recursivamente. El segundo argumento, pattern_to_search , es una expresión regular que queremos buscar en un archivo. Usamos el formato de expresión regular definido en la biblioteca de 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 los archivos que coincidan con esta expresión regular.

Por ejemplo, si quiero buscar archivos Python con la extensión py contiene 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, cada número de línea se agregará al nombre del archivo.

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

Explicación de los comentarios

find es un comando que le permite buscar archivos y otros objetos como directorios y enlaces en subdirectorios de una ruta determinada. Si no especifica una máscara que los nombres de archivos 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 

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 el uso de la carpeta actual:

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

Espero que esto sea de ayuda …

Expandir un poco el grep para dar más información en el resultado, por ejemplo, para obtener el número de línea en el archivo donde se encuentra 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 de cuál es el tipo de archivo, puede restringir su búsqueda especificando extensiones de tipo de archivo para buscar, en este caso archivos .pas o .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 find especifica desde el directorio actual.
  2. -name*.* “: para todos los archivos (-name ” *.pas ” -o -name ” *.dfm “): solo los archivos *.pas OR *.dfm , O especificados con -o
  3. -type f especifica que estás buscando archivos
  4. -print0 y --null en el otro lado del | (tubería) son los cruciales, pasando el nombre de archivo del find al grep incrustado en los xargs , lo que permite el paso de nombres de archivo con espacios en los nombres de archivo, lo que permite grep tratar la ruta y el nombre de archivo como una cadena, y no romperla arriba en cada espacio.

Silver Searcher es una herramienta excelente, pero ripgrep puede ser aún mejor.

Funciona en Linux, Mac y Windows, y se escribió en Hacker News hace un par de meses (este tiene un enlace al blog de Andrew Gallant que tiene un enlace de GitHub):

Ripgrep: una nueva herramienta de búsqueda en línea de comandos

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.

El siguiente comando funcionará bien para este enfoque:

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

Para buscar la cadena y salir 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; 

grep es tu buen amigo para lograr esto.

 grep -r   

si no te importa el caso del texto para encontrar, utiliza

 grep -ir   

Evita las molestias e instala ack-grep. Elimina una gran cantidad de problemas de permisos y presupuestos.

 apt-get install ack-grep 

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

 cd / ack-grep "find my keyword" 

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

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

 ack -i search_string folder_path/* 

Puede ignorar -i para búsqueda sensible a mayúsculas y minúsculas

Me fascina lo fácil que grep lo hace con ‘rl’

 grep -rl 'pattern_to_find' /path/where/to/find -r to find recursively file / directory inside directories.. -l to list files matching the 'pattern' 

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

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

Funciona perfecto.

¡Espero eso ayude!

 grep -Erni + "text you wanna search" 

El comando buscará recursivamente en todos los archivos y directorios del directorio actual e imprimirá el resultado.

Nota: si su salida grep no está coloreada, puede cambiarla usando el alias grep = ‘grep –color = always’ en su archivo shell src

Prueba esto:

 find . | xargs grep 'word' -sl