grep recursivo: excluye directorios específicos

49

Utilizo mucho greps recursivos para encontrar archivos fuente con contenido específico.

grep -Rni "myfunc" .

En bases de código grandes, esto puede ser lento, por lo que uso --incluso para restringir / incluir extensiones en la lista blanca.

grep -Rni --include=*.java "myfunc" .

Sin embargo, sería más eficiente excluir (podar) subdirectorios completos, estoy pensando:

grep -Rni --exclude=/.svn/ "myfunc" .

Pero --exclude solo admite patrones de archivo como * .java arriba. ¿Cómo puedo excluir directorios?

gabor
fuente

Respuestas:

10

Podrías mirar en un ataque .

Acabo de comenzar a usarlo, pero parece adecuado para esto.

Alex Feinman
fuente
ack se ve bastante bien. Es bueno que intuitivamente excluya archivos no deseados. la opción --nogroup da una salida similar a grep -Rni
Gabor
2
Ack es un poco lento. Puedes probar The Silver Searcher (Ag) o ripgrep (rg).
user31389
62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

Fuente: https://stackoverflow.com/questions/2799246/grep-excluding-a-specific-folder-using

Henrik
fuente
17
Tenga en cuenta que esto excluye recursivamente. ./devserá excluido JUNTO CON ./foo/bar/dev. Use --exclude-dir=./devpara aplicar solo al primer caso.
Cory Walker
44
También puede acortar esto un poco haciendo globbing: bash grep -r --exclude-dir={dev,sys,proc} PATTERN data el único problema con el globbing es que no puedo hacer que funcione en mi bash. En ese caso, tengo que mantenerlos separados.
b01
3
También señaló que {} solo funciona si coloca más de 1 entradas, eso significa que --exclude-dir = {home, .svn} funciona pero --exclude-dir = {. Svn} no funcionará. Pierdo mi tiempo para descubrir por qué {} no funciona porque pruebo con 1 entrada en primer lugar.
林果 皞
Si lo usa {}con una sola entrada, probablemente necesite una coma unitaria para convertirla en una matriz (no estoy seguro de cómo Bash maneja eso). En lugar de hacerlo, terminé creando un alias en mis .bash_aliases que recorre una lista de carpetas que normalmente siempre quiero excluir, por ejemplo .git, .svn, .hg, .cache, y luego las agrego a través de un bucle con --exclude-dir $diry luego expande esa matriz en el alias grep.
dragon788
6

puedes usar find en su lugar:

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

Bien, eso es un poco al revés, primero obtienes los resultados grep y luego el camino. ¿Quizás alguien más tiene una mejor respuesta?

Josh
fuente
3
ok, eso me gusta mucho Por supuesto, encontrar es mucho más flexible. la única diferencia entre la salida es que "grep -Rni" imprimirá el nombre del archivo para cada coincidencia, mientras que "find -exec grep" imprimirá el nombre del archivo en una línea y luego una línea para cada coincidencia (con número de línea y contenido de línea ) el uso de "grep" fuerzas -Hni el nombre del archivo que se mostrará en cada línea
Gabor
Gracias por proporcionar la única respuesta que funcionó para los sistemas que son así de crujientes, sin grep --exclude-dir, pero todavía hay que trabajar en ellos
Dmitri DB
2

Aquí hay un ejemplo completo de un script en uno de mis proyectos que podría ayudar, llamo a este archivo "all_source" (marcado como ejecutable) y lo pongo en el directorio raíz de mi proyecto y luego lo llamo como grep myfunc $(./all_source)el tipo al final del script es totalmente Opcional.

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

Este script devuelve todos los nombres de archivo en el proyecto que coinciden *.h, *.cpp, *.c, *.lua, *.*awk, pero no busca en todas las carpetas llamadas carpetas .svn y gen, así como omite las carpetas para ./liby ./vc6(pero solo las que están directamente fuera de la raíz del proyecto). Entonces, cuando lo haces grep myfunc $(./all_source), solo greps en esos archivos. También deberá llamar a esto desde el directorio raíz del proyecto.

Mike Nelson
fuente
0

También existe la opción -prune para encontrar:

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print
misiu_mp
fuente
0

Puedes intentar hacer esto:

grep -R  "myfunc" . | grep -v path_to_exclude/

Por ejemplo: si no desea buscar el contenido en los archivos de registro, simplemente haga lo siguiente:

grep -R "myfunc" . | grep -v log/
Akshatha
fuente