recursivo - buscar un archivo en linux terminal
¿Cómo encuentro todos los archivos que contienen texto específico en Linux? (30)
¿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 usa find como en su ejemplo, agregue -s
( --no-messages
) a grep
, y 2>/dev/null
al final del comando para evitar muchos mensajes de Permiso denegado 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 al buscar texto específico, en plataformas similares a Unix. El comando de find 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 inténtelos, 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 alrededor de:
rg ''text-to-find-here'' / -l
ag ''text-to-find-here'' / -l
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! Así que en los ejemplos anteriores, es mejor que sustituyas '' / '' por un nombre de subdirectorio, por ejemplo, "/ home" dependiendo de dónde quieras buscar ...
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, encontré 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á 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.
Lista de nombres de archivos que contienen un texto dado
En primer lugar, creo que has usado -H
lugar de -l
. También puedes intentar agregar el texto dentro de las comillas seguido de {} /
.
find / -type f -exec grep -l "text-to-find-here" {} /;
Ejemplo
Digamos que está buscando archivos que contengan el texto específico "Licencia Apache" dentro de su directorio. Mostrará resultados 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 la sensibilidad del caso
Incluso si no usa el caso como "texto" vs "TEXTO", puede usar el interruptor -i
para ignorar el caso. Puedes leer más detalles here .
Espero que esto te ayude.
grep
( GNU o BSD )
Puede usar la herramienta grep
para buscar recursivamente la carpeta actual, como:
grep -r "class foo" .
Nota: -r
- Busca de forma recursiva los subdirectorios.
También puede usar la sintaxis de globbing para buscar en archivos específicos como:
grep "class foo" **/*.c
Nota: Al usar la opción de globbing ( **
), 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 usar **/*.*
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 limitar su búsqueda o use la sintaxis de find
lugar de:
find . -name "*.php" -execdir grep -nH --color=auto foo {} '';''
Alternativamente, utilice ripgrep
.
ripgrep
Si estás trabajando en proyectos más grandes o archivos grandes, deberías usar ripgrep
en ripgrep
lugar, como:
rg "class foo" .
Verifique los documentos, los pasos de instalación o el código fuente en la ripgrep .
Es mucho más rápido que cualquier otra herramienta como GNU / BSD grep
, ucg
, ag
, sift
, ack
, pt
o similar, ya que está construido sobre el motor de expresiones regulares de Rust que utiliza autómatas finitos, SIMD y optimizaciones literales agresivas para hacer la búsqueda muy rápido .
Admite los patrones de ignorar especificados en los archivos .gitignore
, por lo que una única ruta de archivo se puede comparar con varios patrones globales simultáneamente.
Puede utilizar los parámetros comunes tales como:
-
-i
- Búsqueda insensible. -
-I
- Ignora los archivos binarios. -
-w
- Busca las palabras completas (en oposición a la coincidencia parcial de palabras). -
-n
- Muestra la línea de tu partido. -
-C
/--context
(ej.-C5
) - Aumenta el contexto, por lo que ve el código circundante. -
--color=auto
- Marca 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
.
Aquí están las varias listas 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
El siguiente comando funcionará bien para este enfoque:
find ./ -name "file_pattern_name" -exec grep -r "pattern" {} /;
Escribí un script en Python que hace algo similar. Así es como uno debe usar este script.
./sniff.py path pattern_to_search [file_pattern]
El primer argumento, path
, es el directorio en el que buscaremos de forma recursiva. 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 . En este guión, 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 py
contiene Pool(
seguido de la palabra 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.
Espero que esto sea de ayuda ...
Expandir un poco el grep
para dar más información en la salida, 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 qué tipo de archivo es, puede acotar su búsqueda especificando extensiones de tipo de archivo para buscar, en este caso .pas
O archivos .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:
-
.
en lafind
especifica desde el directorio actual. -
-name
"*.*
": para todos los archivos (-name "*.pas
" -o -name "*.dfm
"): Solo los archivos*.pas
O*.dfm
, O especificados con-o
-
-type f
especifica que buscas archivos -
-print0
y--null
en el otro lado de la|
(pipe) son los cruciales, pasando el nombre de archivo delfind
algrep
incrustado en losxargs
, permitiendo el paso de los nombres de los archivos CON espacios en los nombres de archivo, lo que permite a grep tratar la ruta y el nombre de archivo como una cadena, y no romperlos arriba en cada espacio.
Evita la molestia e instala ack-grep. Se elimina una gran cantidad de 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"
Grep es tu buen amigo para lograrlo.
grep -r <text_fo_find> <directory>
Si no te importa el caso del texto para encontrarlo, usa
grep -ir <text_to_find> <directory>
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 la búsqueda de mayúsculas y minúsculas
Hay una nueva utilidad llamada The Silversearcher
sudo apt install silversearcher-ag
Trabaja estrechamente con Git y otros VCS. Así que no obtendrás nada en un .git u otro directorio.
Usted puede simplemente utilizar
ag -ia "Search query"
Y hará la tarea por ti!
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 toda la palabra. -
-l
(minúscula L) se puede agregar para simplemente dar el nombre del archivo de los archivos coincidentes.
Junto con estos, --include
, --include
, --include
--exclude-dir
flags podrían usarse para una búsqueda eficiente:
Esto solo buscará a través de aquellos archivos que tienen 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) en particular a través
--exclude-dir
parámetro--exclude-dir
. Por ejemplo, esto excluirá los dirs 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 más opciones verifique man grep
.
Me fascina lo simple que lo hace grep 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 simplemente perfecto ..
¡Espero eso ayude!
Para buscar la cadena y la salida 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 del 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;
Prueba esto:
find . | xargs grep ''word'' -sl
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 su directorio raíz.
También puedes 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 archivo .gitignore
.
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í mismo". -
/
significa comenzar en la raíz de su máquina.
Puedes usar esto:
grep -inr "Text" folder/to/be/searched/
Puedes usar:
grep -r "string to be searched" /path/to/dir
La r
significa recursiva y, por lo tanto, buscará en la ruta especificada y también en sus subdirectorios. Esto le dirá el nombre del archivo y también 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 coincidencias
Si su grep
no admite la búsqueda recursiva, puede combinar find
con xargs
:
find / -type f | xargs grep ''text-to-find-here''
Encuentro esto más fácil de recordar que el formato para find -exec
.
Esto generará el nombre del archivo y el contenido de la línea coincidente, por ejemplo,
/home/rob/file:text-to-find-here
Banderas opcionales que puede querer agregar a grep
:
-
-i
- búsqueda insensible a mayú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)
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 (esto tiene un enlace al Blog de Andrew Gallant que tiene un enlace de GitHub):
Ripgrep - Una nueva herramienta de búsqueda de línea de comandos
Todas las respuestas anteriores sugieren grep y encontrar. Pero hay otra manera: usar el comandante de medianoche
Es una utilidad gratuita (30 años de antigüedad, probada por el tiempo) que es visual sin ser GUI. Tiene toneladas de funciones, encontrar archivos es solo una de ellas.
Tratar:
find . -name "*.txt" | xargs grep -i "text_pattern"
Tratar:
find / -type f -exec grep -H ''text-to-find-here'' {} /;
que buscará 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 actual de la carpeta:
find ./ -type f -exec grep -H ''text-to-find-here'' {} /;
Un simple find
puede funcionar a la mano. alias en tu archivo ~/.bashrc
:
alias ffind find / -type f | xargs grep
Iniciar un nuevo terminal y emitir:
ffind ''text-to-find-here''
Use pwd
para buscar desde cualquier directorio en el que esté, recursionando 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 nuevas .
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!
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.
grep
puede usarse 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.
find /path -type f -exec grep -l "string" {} /;
Explicación de los 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 los archivos deben cumplir, enumera todos los objetos del 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
grep -insr "pattern" *
-
i
: Ignore las distinciones entre mayúsculas y minúsculas tanto en PATTERN como en los archivos de entrada. -
n
: Prefija cada línea de salida con el número de línea basado en 1 dentro de su archivo de entrada. -
s
: suprima los mensajes de error sobre archivos inexistentes o ilegibles. -
r
: Leer todos los archivos en cada directorio, recursivamente.