¿Cómo hago grep recursivamente?

1682

¿Cómo recursivamente greptodos los directorios y subdirectorios?

find . | xargs grep "texthere" *
wpiri
fuente
110
@ 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.
Ben
8
ag es mi forma favorita de hacer esto ahora github.com/ggreer/the_silver_searcher
dranxo
1
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.

Vinko Vrsalovic
fuente
39
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.

christangrant
fuente
3
Funciona muy bien con grep que viene con Linux y Cygwin, pero no con el que viene con AIX.
Retenido el
1
@KrzysztofWolny: `` en lugar de =funcionar bien en Ubuntu. PD: se supone que es un espacio invertido, pero el analizador de rebajas SO falló.
Dan Dascalescu
44
@DanDascalescu Voté por el grep, no por el Ag, para que lo sepas :)
Bernhard
1
¿Tenemos una opción para excluir un directorio mientras buscamos recursivamente?
Tom Taylor
A cygwin de Windows le gustan las comillas dobles--include "*.txt" --include "*.TXT"
Bob Stein
127

También:

find ./ -type f -print0 | xargs -0 grep "foo"

Pero grep -res una mejor respuesta.

Kurt
fuente
14
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.
Wes
Esto funciona en todos * nix porque es POSIX 7
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
find ./ -type f -print0 | xargs -0 grep "foo"
aehlke
118

Ahora siempre uso (incluso en Windows con GoW - Gnu en Windows ):

grep --include="*.xxx" -nRHI "my Text to grep" *

Eso incluye las siguientes opciones:

--include=PATTERN

Recurrir en directorios solo buscando coincidencia de archivos PATTERN.

-n, --line-number

Prefije cada línea de salida con el número de línea dentro de su archivo de entrada.

(Nota: phuclv agrega en los comentarios que -ndisminuye mucho el rendimiento , por lo que es posible que desee omitir esa opción)

-R, -r, --recursive

Lea todos los archivos en cada directorio, de forma recursiva; Esto es equivalente a la -d recurseopción.

-H, --with-filename

Imprima el nombre del archivo para cada partido.

-I     

Procese un archivo binario como si no contuviera datos coincidentes;
Esto es equivalente a la --binary-files=without-matchopción.

Y puedo agregar ' i' ( -nRHIi), si quiero resultados que no distingan entre mayúsculas y minúsculas.

Puedo conseguir:

/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43:            'git.hidden'      => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21:            $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32:        $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20:    protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170:     * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176:        return $this->hidden;
...
VonC
fuente
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á:

find . -type f -exec grep -n "stuff" {} \; -print

Acordado por Solarisy HP-UX.

torre
fuente
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.
torre
19

pegajoso **

Usando grep -rtrabajos, pero puede exagerar, especialmente en carpetas grandes.

Para un uso más práctico, aquí está la sintaxis que usa la sintaxis global ( **):

grep "texthere" **/*.txt

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:

git grep "pattern"

Que es mucho más rápido.

ripgrep

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í .

kenorb
fuente
3
Gracias por la sugerencia de git grep, ¡es muy útil y no lo sabía!
Basya
2
Gracias por la sugerencia de ripgrep. Es mucho más rápido
Lo que sería genial
11

Para encontrar el nombre de filescon pathrecursivamente que contiene el stringuso particular debajo del comando para UNIX:

find . | xargs grep "searched-string"

para Linux:

grep -r "searched-string" .

encontrar un archivo en el UNIXservidor

find . -type f -name file_name

encontrar un archivo en el servidor LINUX

find . -name file_name
Girdhar Singh Rathore
fuente
11

solo los nombres de archivo pueden ser útiles también

grep -r -l "foo" .
chim
fuente
10

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

grep -RH "cats" ../TomAndJerry                   #relative directory

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory

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/

SarcásticoSully
fuente
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.

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 )

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
dranxo
fuente
6

Esto debería funcionar:

grep -R "texthere" *
sumit kumar
fuente
6

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:

find -type f -exec grep -Hn "texthere" {} +

Donde -nimprime el número de línea.

fedorqui 'así que deja de dañar'
fuente
2
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):

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"

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"

Arkod
fuente
4

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

grep [options] PATTERN [FILE...]

[opciones]

-R, -r, --recursive

Lea todos los archivos en cada directorio, de forma recursiva.

Esto es equivalente a la opción -d recurseo --directories=recurse.

http://linuxcommand.org/man_pages/grep1.html

ayuda grep

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

Alternativas

ack( http://beyondgrep.com/ )

ag( http://github.com/ggreer/the_silver_searcher )

Geoffrey Hale
fuente
4

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.

hughdbrown
fuente
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:

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

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í :)

user3606336
fuente
3

A continuación se presentan el comando para la búsqueda de una Stringforma recursiva sobre Unixy Linuxmedio ambiente.

para UNIXcomando es:

find . -name "string to be searched" -exec grep "text" "{}" \;

para Linuxcomando es:

grep -r "string to be searched" .
Girdhar Singh Rathore
fuente
2

Para una lista de banderas disponibles:

grep --help 

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:

grep -rni "texthere" /

banderas utilizadas aquí:

  • -r recursivo
  • -n imprimir número de línea con salida
  • -i ignorar caso
JSON C11
fuente
1

Supongo que esto es lo que intentas escribir

grep myText $(find .)

y esto puede ser algo más útil si desea encontrar los archivos grep hit

grep myText $(find .) | cut -d : -f 1 | sort | uniq
Victor Faria
fuente
Es muy intuitivo: por ejemplo: grep -i acc $ (find. -Name "ejecución *. *")
Yu Shen
1

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.

git grep "texthere"

Incluso si el directorio no está organizado, solo lo organizo y uso git grep.

Zstack
fuente
0

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.

m.thome
fuente
¿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 :-)

grep -r texthere .|grep .txt

PJ Brunet
fuente
0

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
James Brown
fuente
-2
The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .
Poo
fuente
77
Esto no agrega mucho a otras respuestas
Mel