@ TC1 Lo triste es que grep puede responder la pregunta (al menos GNU grep): grep --help | grep recursivo
Frank Schmitt
77
Si utiliza frecuentemente grep para realizar búsquedas recursivas (especialmente si realiza manualmente muchas extracciones de archivos / directorios), puede encontrar útil ack (una alternativa grep muy fácil de programar).
Nick McCurdy
19
En realidad, ni -r ni - trabajo recurrente en el cuadro de Solaris que uso en el trabajo. Y la página de manual de grep no menciona nada recursivo. Tuve que recurrir para encontrar y xargs a mí mismo.
grep -rin xlsx *.plno funciona para mí en Redhat Linux. Me sale un error de "no coincidencia".
Bulrush
Respuestas:
2507
grep -r "texthere" .
El primer parámetro representa la expresión regular a buscar, mientras que el segundo representa el directorio que se debe buscar. En este caso, .significa el directorio actual.
Nota: Esto funciona para GNU grep, y en algunas plataformas como Solaris debe usar específicamente GNU grep en lugar de la implementación heredada. Para Solaris este es el ggrepcomando.
Nota: "grep -r" solo funciona en greps más nuevos. No funciona en el grep que viene con, AIX 5.3por ejemplo.
Retenido
110
Use grep -R para seguir enlaces simbólicos.
Eloff
53
Es bueno saber que "-i" haría que no distinga entre mayúsculas y minúsculas, y "-n" también incluye el número de línea para cada resultado coincidente.
Sadegh el
24
También es bueno saberlo, si solo está buscando una cadena fija y no una expresión regular, use la opción -F. le ahorrará un montón de tiempo al no invocar el analizador de expresiones regulares. muy útil si está buscando muchos archivos.
Jeff
66
alias rgrep = 'grep -r'
totten
679
Si conoce la extensión o el patrón del archivo que desea, otro método es usar la --includeopción:
grep -r --include "*.txt" texthere .
También puede mencionar archivos para excluir con --exclude.
Ag
Si busca con frecuencia en el código, Ag (The Silver Searcher) es una alternativa mucho más rápida que grep, que está personalizada para buscar código. Por ejemplo, es recursivo de forma predeterminada e ignora automáticamente los archivos y directorios enumerados .gitignore, por lo que no tiene que seguir pasando las mismas opciones de exclusión engorrosas para grep o encontrar.
O si no desea preocuparse por los espacios en los nombres de archivo, find . -type f -exec grep "foo" '{}' \;funciona bien donde sea compatible.
Edd Steel
44
Si va a buscar tuberías a través de xargs a grep, Y si solo está buscando una cadena fija (es decir, no una expresión regular), podría beneficiarse de invocar la opción grep -F, por lo que grep no cargará el motor de expresiones regulares. para cada invocación Si hay muchos archivos, será mucho más rápido.
Jeff
2
encontrar . -tipo f -exec grep -Hu "foo" {} \; es lo que uso, ya que da el nombre del archivo.
Gow parece prometedor, más nuevo que las utilidades GNU de Windows que he estado usando.
Probándolo
¿Cuál es el significado del último personaje * aquí?
lorniper el
2
@lorniper hace que el shell seleccione todos los archivos y carpetas en su directorio actual, haciendo que el grep se aplique a esos archivos y (recursivamente debido a la -Ropción) a las carpetas.
VonC
2
@lorniper Noy exactamente: *o .es un patrón global (interpretado por el shell): unix.stackexchange.com/a/64695/7490 . ' .' seleccionará también archivos de puntos o carpetas de puntos (como .git/)
VonC
anteriormente siempre he usado, grep -rnIpero luego aprendí que -ndisminuye mucho el rendimiento, así que solo lo uso cuando realmente lo necesito y normalmente lo -rI
usaré
25
En los sistemas POSIX, no encuentra el -rparámetro grepy grep -rn "stuff" .no se ejecutará, pero si usa el findcomando, lo hará:
Cuál es el significado de {} \; -print respectivamente?
user1169587
3
En la -execopción: el símbolo {}es una referencia al nombre de archivo que actualmente encuentra la findherramienta (es decir, hacer algo con el nombre de archivo que encontramos), también la -execopción debe terminarse con el ;símbolo (para marcar el final de los comandos exec), pero porque esto es todo ejecutándose en un shell, ese símbolo debe escaparse ... y finalmente la -printopción permite a la findherramienta imprimir nombres de archivos encontrados en la pantalla.
Para proyectos más grandes, la herramienta de grepping más rápida es ripgrepque greps los archivos de forma recursiva por defecto:
rg "pattern" .
Está construido sobre el motor regex de Rust, que utiliza autómatas finitos, SIMD y optimizaciones literales agresivas para que la búsqueda sea muy rápida. Consulte el análisis detallado aquí .
Si solo desea seguir directorios reales, y no enlaces simbólicos,
grep -r "thingToBeFound" directory
Si desea seguir enlaces simbólicos, así como directorios reales (tenga cuidado con la recursión infinita),
grep -R "thing to be found" directory
Como estás tratando de hacer greps recursivamente, las siguientes opciones también pueden ser útiles para ti:
-H: outputs the filename with the line
-n: outputs the line number in the file
Entonces, si desea encontrar todos los archivos que contienen Darth Vader en el directorio actual o cualquier subdirectorio y capturar el nombre de archivo y el número de línea, pero no desea que la recursión siga enlaces simbólicos, el comando sería
grep -rnH "Darth Vader" .
Si desea encontrar todas las menciones de la palabra gato en el directorio
/home/adam/Desktop/TomAndJerry
y actualmente estás en el directorio
/home/adam/Desktop/WorldDominationPlot
y desea capturar el nombre de archivo pero no el número de línea de cualquier instancia de la cadena "gatos", y desea que la recursión siga enlaces simbólicos si los encuentra, puede ejecutar cualquiera de los siguientes
Gran respuesta. Los modificadores adicionales (-rnh) son muy útiles, así que gracias por sugerirlos.
semtex41
8
ag es mi forma favorita de hacer esto ahora github.com/ggreer/the_silver_searcher . Básicamente es lo mismo que ack pero con algunas optimizaciones más.
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Si está buscando un contenido específico en todos los archivos desde una estructura de directorios, puede usarlo findya que tiene más claro lo que está haciendo:
find -type f -exec grep -l "texthere" {} +
Tenga en cuenta que -l(minúscula de L) muestra el nombre del archivo que contiene el texto. Elimínelo si desea imprimir la coincidencia en sí. O use -Hpara obtener el archivo junto con el partido. Todos juntos, otras alternativas son:
Votaron por ser la única findsolución para evitar el uso innecesario xargsy el uso en +lugar de \;con -exec, evitando toneladas de lanzamientos innecesarios de procesos. :-)
ShadowRanger
6
Este es el que funcionó para mi caso en mi máquina actual (git bash en Windows 7):
Siempre olvido los -print0 y -0 para los caminos con espacios.
EDITAR: Mi herramienta preferida ahora es ripgrep: https://github.com/BurntSushi/ripgrep/releases . Es realmente rápido y tiene mejores valores predeterminados (como recursivo por defecto). Mismo ejemplo que mi respuesta original pero usando ripgrep:rg -g "*.cs" "content pattern"
En 2018, desea usar ripgrepo the-silver-searcherporque son mucho más rápidos que las alternativas.
Aquí hay un directorio con 336 subdirectorios de primer nivel:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
En OSX, esta instala ripgrep: brew install ripgrep. Esto instala silver-searcher: brew install the_silver_searcher.
La velocidad es importante si necesita hacer esto con frecuencia, pero la mayoría de nosotros nos encontramos haciendo esto solo algunas veces al año como máximo. Instalar la última herramienta juju de terceros de forma rápida es excesivo y las soluciones que no han cambiado mucho desde 1978 son buenas para conocer.
tripleee
Me parece muy inverosímil que un programador busque texto en un árbol fuente solo varias veces al año. Pero incluso desde el punto de vista de la usabilidad, rgtiene una ventaja considerable sobre la combinación de un comando grep recursivo desde cero. Usando rg: rg foo. El uso de herramientas de UNIX: find . | xargs grep foo. Y si alguno de sus archivos tiene una cita, debe usarlo find . -print0 | xargs -0 grep foo. ¿Vas a recordar eso si lo usas varias veces al año?
hughdbrown
1
Estás olvidando find . -type f -exec grep 'regex' {} +cuál es realmente fácil de recordar si usas estas herramientas con regularidad. Pero de todos modos, probablemente deba ejecutar ctagso etagsen su árbol de origen si necesita encontrar cosas con frecuencia.
tripleee
He estado usando ripgrep y es genial. Pero el buscador de plata es fantástico para los programadores. +1
Matt
3
En mi servidor IBM AIX (versión del sistema operativo: AIX 5.2), use:
Devuelve todas las coincidencias para el texto regexp aquí en el directorio actual, con el número de línea correspondiente:
grep -rn "texthere" .
Devuelve todas las coincidencias para texthere , comenzando en el directorio raíz, con el número de línea correspondiente e ignorando mayúsculas y minúsculas:
Tenga en cuenta que los find . -type f | xargs grep whatevertipos de soluciones se encontrarán con errores de "Lista de argumentos a largo" cuando haya demasiados archivos que coincidan con find.
La mejor opción es, grep -rpero si eso no está disponible, úselo find . -type f -exec grep -H whatever {} \;en su lugar.
¿Eh? xargses específicamente una solución alternativa para el problema "Lista de argumentos demasiado larga".
tripleee
2
Bueno, no - xargs es específicamente para convertir una serie de argumentos en un arglista, pero sí, es cierto que los xargs modernos cuando se usan con -s y / o -L pueden lidiar con arglistas muy largos al romper en invocaciones de comandos múltiples, pero no está configurado de esa manera por defecto (y no estaba en ninguna de las respuestas anteriores). A modo de ejemplo:find . -type f | xargs -L 100 grep whatever
m.thome
¿En qué plataforma estaría eso? POSIXxargs está estandarizado para tener este comportamiento fuera de la caja. "La xargsutilidad limitará la longitud de la línea de comando de modo que cuando se invoque la línea de comando, las listas combinadas de argumentos y entorno ... no excedan {ARG_MAX} -2048 bytes".
tripleee
Hm. Si bien los documentos de GNU son menos claros que Posix sobre esta base, y ya no tengo acceso a la máquina que me hizo hacer esta declaración, no puedo confirmar mi interpretación original sobre ninguna implementación actual. Por supuesto, grep recursivo es preferible si está disponible, pero hay pocas razones para evitar la receta xargs (sin embargo, use -H para evitar que la invocación final de grep pase solo un nombre de archivo).
m.thome
0
Solo por diversión, una búsqueda rápida y sucia de archivos * .txt si la respuesta @christangrant es demasiado para escribir :-)
Aquí hay una función recursiva (probada a la ligera con bash y sh) que atraviesa todas las subcarpetas de una carpeta determinada ($ 1) y utiliza grepbúsquedas para una cadena dada ($ 3) en archivos dados ($ 2):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
Ejecutándolo y un ejemplo de salida:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename
grep -rin xlsx *.pl
no funciona para mí en Redhat Linux. Me sale un error de "no coincidencia".Respuestas:
El primer parámetro representa la expresión regular a buscar, mientras que el segundo representa el directorio que se debe buscar. En este caso,
.
significa el directorio actual.Nota: Esto funciona para GNU grep, y en algunas plataformas como Solaris debe usar específicamente GNU grep en lugar de la implementación heredada. Para Solaris este es el
ggrep
comando.fuente
AIX 5.3
por ejemplo.Si conoce la extensión o el patrón del archivo que desea, otro método es usar la
--include
opción:También puede mencionar archivos para excluir con
--exclude
.Ag
Si busca con frecuencia en el código, Ag (The Silver Searcher) es una alternativa mucho más rápida que grep, que está personalizada para buscar código. Por ejemplo, es recursivo de forma predeterminada e ignora automáticamente los archivos y directorios enumerados
.gitignore
, por lo que no tiene que seguir pasando las mismas opciones de exclusión engorrosas para grep o encontrar.fuente
=
funcionar bien en Ubuntu. PD: se supone que es un espacio invertido, pero el analizador de rebajas SO falló.grep
, no por el Ag, para que lo sepas :)--include "*.txt" --include "*.TXT"
También:
Pero
grep -r
es una mejor respuesta.fuente
find . -type f -exec grep "foo" '{}' \;
funciona bien donde sea compatible.find ./ -type f -print0 | xargs -0 grep "foo"
Ahora siempre uso (incluso en Windows con GoW - Gnu en Windows ):
Eso incluye las siguientes opciones:
(Nota: phuclv agrega en los comentarios que
-n
disminuye mucho el rendimiento , por lo que es posible que desee omitir esa opción)Y puedo agregar '
i
' (-nRHIi
), si quiero resultados que no distingan entre mayúsculas y minúsculas.Puedo conseguir:
fuente
-R
opción) a las carpetas.*
o.
es un patrón global (interpretado por el shell): unix.stackexchange.com/a/64695/7490 . '.
' seleccionará también archivos de puntos o carpetas de puntos (como.git/
)grep -rnI
pero luego aprendí que-n
disminuye mucho el rendimiento, así que solo lo uso cuando realmente lo necesito y normalmente lo-rI
En los sistemas POSIX, no encuentra el
-r
parámetrogrep
ygrep -rn "stuff" .
no se ejecutará, pero si usa elfind
comando, lo hará:find . -type f -exec grep -n "stuff" {} \; -print
Acordado por
Solaris
yHP-UX
.fuente
-exec
opción: el símbolo{}
es una referencia al nombre de archivo que actualmente encuentra lafind
herramienta (es decir, hacer algo con el nombre de archivo que encontramos), también la-exec
opción debe terminarse con el;
símbolo (para marcar el final de los comandos exec), pero porque esto es todo ejecutándose en un shell, ese símbolo debe escaparse ... y finalmente la-print
opción permite a lafind
herramienta imprimir nombres de archivos encontrados en la pantalla.pegajoso
**
Usando
grep -r
trabajos, pero puede exagerar, especialmente en carpetas grandes.Para un uso más práctico, aquí está la sintaxis que usa la sintaxis global (
**
):que agrupa solo archivos específicos con el patrón seleccionado. Funciona para shells compatibles como Bash +4 o zsh .
Para activar esta función, ejecute:
shopt -s globstar
.Consulte también: ¿Cómo encuentro todos los archivos que contienen texto específico en Linux?
git grep
Para proyectos bajo control de versión Git, use:
Que es mucho más rápido.
ripgrep
Para proyectos más grandes, la herramienta de grepping más rápida es
ripgrep
que greps los archivos de forma recursiva por defecto:Está construido sobre el motor regex de Rust, que utiliza autómatas finitos, SIMD y optimizaciones literales agresivas para que la búsqueda sea muy rápida. Consulte el análisis detallado aquí .
fuente
Para encontrar el nombre de
files
conpath
recursivamente que contiene elstring
uso particular debajo del comando paraUNIX
:para
Linux
:encontrar un archivo en el
UNIX
servidorencontrar un archivo en el servidor LINUX
fuente
solo los nombres de archivo pueden ser útiles también
fuente
Si solo desea seguir directorios reales, y no enlaces simbólicos,
Si desea seguir enlaces simbólicos, así como directorios reales (tenga cuidado con la recursión infinita),
Como estás tratando de hacer greps recursivamente, las siguientes opciones también pueden ser útiles para ti:
Entonces, si desea encontrar todos los archivos que contienen Darth Vader en el directorio actual o cualquier subdirectorio y capturar el nombre de archivo y el número de línea, pero no desea que la recursión siga enlaces simbólicos, el comando sería
Si desea encontrar todas las menciones de la palabra gato en el directorio
y actualmente estás en el directorio
y desea capturar el nombre de archivo pero no el número de línea de cualquier instancia de la cadena "gatos", y desea que la recursión siga enlaces simbólicos si los encuentra, puede ejecutar cualquiera de los siguientes
Fuente:
ejecutando "grep --help"
Una breve introducción a los enlaces simbólicos, para cualquiera que lea esta respuesta y se confunda con mi referencia a ellos: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
fuente
ag es mi forma favorita de hacer esto ahora github.com/ggreer/the_silver_searcher . Básicamente es lo mismo que ack pero con algunas optimizaciones más.
Aquí hay un breve punto de referencia. Borro el caché antes de cada prueba (cf /ubuntu/155768/how-do-i-clean-or-disable-the-memory-cache )
fuente
Esto debería funcionar:
fuente
Si está buscando un contenido específico en todos los archivos desde una estructura de directorios, puede usarlo
find
ya que tiene más claro lo que está haciendo:Tenga en cuenta que
-l
(minúscula de L) muestra el nombre del archivo que contiene el texto. Elimínelo si desea imprimir la coincidencia en sí. O use-H
para obtener el archivo junto con el partido. Todos juntos, otras alternativas son:Donde
-n
imprime el número de línea.fuente
find
solución para evitar el uso innecesarioxargs
y el uso en+
lugar de\;
con-exec
, evitando toneladas de lanzamientos innecesarios de procesos. :-)Este es el que funcionó para mi caso en mi máquina actual (git bash en Windows 7):
Siempre olvido los -print0 y -0 para los caminos con espacios.
EDITAR: Mi herramienta preferida ahora es ripgrep: https://github.com/BurntSushi/ripgrep/releases . Es realmente rápido y tiene mejores valores predeterminados (como recursivo por defecto). Mismo ejemplo que mi respuesta original pero usando ripgrep:
rg -g "*.cs" "content pattern"
fuente
grep -r "texthere" .
(período de aviso al final)(^ crédito: https://stackoverflow.com/a/1987928/1438029 )
Aclaración:
grep -r "texthere" /
(grep recursivamente todos los directorios y subdirectorios)grep -r "texthere" .
(recursivamente grep estos directorios y subdirectorios)grep recursivo
ayuda grep
$ grep --help
Alternativas
ack
( http://beyondgrep.com/ )ag
( http://github.com/ggreer/the_silver_searcher )fuente
En 2018, desea usar
ripgrep
othe-silver-searcher
porque son mucho más rápidos que las alternativas.Aquí hay un directorio con 336 subdirectorios de primer nivel:
En OSX, esta instala
ripgrep
:brew install ripgrep
. Esto instalasilver-searcher
:brew install the_silver_searcher
.fuente
rg
tiene una ventaja considerable sobre la combinación de un comando grep recursivo desde cero. Usandorg
:rg foo
. El uso de herramientas de UNIX:find . | xargs grep foo
. Y si alguno de sus archivos tiene una cita, debe usarlofind . -print0 | xargs -0 grep foo
. ¿Vas a recordar eso si lo usas varias veces al año?find . -type f -exec grep 'regex' {} +
cuál es realmente fácil de recordar si usas estas herramientas con regularidad. Pero de todos modos, probablemente deba ejecutarctags
oetags
en su árbol de origen si necesita encontrar cosas con frecuencia.En mi servidor IBM AIX (versión del sistema operativo: AIX 5.2), use:
esto imprimirá la ruta / nombre del archivo y el número de línea relativa en el archivo como:
./inc/xxxx_x.h
2865: / ** Descripción: stringYouWannaFind * /
de todos modos, funciona para mí :)
fuente
A continuación se presentan el comando para la búsqueda de una
String
forma recursiva sobreUnix
yLinux
medio ambiente.para
UNIX
comando es:para
Linux
comando es:fuente
Para una lista de banderas disponibles:
Devuelve todas las coincidencias para el texto regexp aquí en el directorio actual, con el número de línea correspondiente:
Devuelve todas las coincidencias para texthere , comenzando en el directorio raíz, con el número de línea correspondiente e ignorando mayúsculas y minúsculas:
banderas utilizadas aquí:
-r
recursivo-n
imprimir número de línea con salida-i
ignorar casofuente
Supongo que esto es lo que intentas escribir
y esto puede ser algo más útil si desea encontrar los archivos grep hit
fuente
Lanzando mis dos centavos aquí. Como otros ya mencionaron grep -r no funciona en todas las plataformas. Esto puede sonar tonto pero siempre uso git.
Incluso si el directorio no está organizado, solo lo organizo y uso git grep.
fuente
Tenga en cuenta que los
find . -type f | xargs grep whatever
tipos de soluciones se encontrarán con errores de "Lista de argumentos a largo" cuando haya demasiados archivos que coincidan con find.La mejor opción es,
grep -r
pero si eso no está disponible, úselofind . -type f -exec grep -H whatever {} \;
en su lugar.fuente
xargs
es específicamente una solución alternativa para el problema "Lista de argumentos demasiado larga".find . -type f | xargs -L 100 grep whatever
xargs
está estandarizado para tener este comportamiento fuera de la caja. "Laxargs
utilidad limitará la longitud de la línea de comando de modo que cuando se invoque la línea de comando, las listas combinadas de argumentos y entorno ... no excedan {ARG_MAX} -2048 bytes".Solo por diversión, una búsqueda rápida y sucia de archivos * .txt si la respuesta @christangrant es demasiado para escribir :-)
grep -r texthere .|grep .txt
fuente
Aquí hay una función recursiva (probada a la ligera con bash y sh) que atraviesa todas las subcarpetas de una carpeta determinada ($ 1) y utiliza
grep
búsquedas para una cadena dada ($ 3) en archivos dados ($ 2):Ejecutándolo y un ejemplo de salida:
fuente
fuente