grep ricorsivo: esclude directory specifiche


49

Uso molto grep ricorsivo per trovare file sorgente con contenuti specifici.

grep -Rni "myfunc" .

Su basi di codice di grandi dimensioni, questo può rallentare, quindi uso --incldue per limitare / autorizzare le estensioni.

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

Tuttavia, sarebbe più efficiente escludere (potare) intere sottodirectory, sto pensando:

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

Ma --exclude supporta solo modelli di file come * .java sopra. Come posso escludere le directory?

Risposte:


10

Si potrebbe guardare in ack .

Ho appena iniziato a usarlo ma sembra adatto per questo.


ack sembra abbastanza buono. bello che escluda intuitivamente i file indesiderati. l'opzione --nogroup fornisce un output simile a grep -Rni
gabor

2
Ack è un po 'lento. Puoi provare The Silver Searcher (Ag) o ripgrep (rg).
user31389

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

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


17
Si noti che questo esclude ricorsivamente. ./devsarà escluso SOLO CON ./foo/bar/dev. Utilizzare --exclude-dir=./devper applicare solo al primo caso.
Cory Walker,

4
Puoi anche accorciare un po 'questo con il globbing: bash grep -r --exclude-dir={dev,sys,proc} PATTERN data l'unico problema con il globbing è che non riesco a farlo funzionare nella mia bash. In tal caso, devo tenerli separati.
b01,

3
Ho anche notato che {} funziona solo se inserisci più di 1 voci, ciò significa che --exclude-dir = {home, .svn} funziona ma --exclude-dir = {. Svn} non funziona. Perdo il mio tempo a capire perché {} non funziona perché provo con 1 voce in primo luogo.
林果 皞

Se lo usi {}con una singola voce, probabilmente hai bisogno di una virgola unaria per renderla un array (non sei sicuro di come Bash lo gestisca). Invece di farlo ho finito per creare un alias nei miei .bash_aliases che scorre su un elenco di cartelle che di solito voglio sempre escludere, ad esempio .git, .svn, .hg, .cache, e poi li aggiungo tramite un ciclo con --exclude-dir $dire quindi espandi quell'array nell'alias grep.
dragon788,

6

puoi invece usare find:

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

OK, quindi è un po 'indietro, ottieni prima i risultati grep e poi il percorso. Forse qualcun altro ha una risposta migliore?


3
ok, mi piace molto. ovviamente trovare è molto più flessibile. l'unica differenza tra l'output è che "grep -Rni" stamperà il nome del file per ogni corrispondenza, mentre "find -exec grep" stamperà il nome del file su una riga e quindi una riga per ogni corrispondenza (con numero di riga e contenuto della riga ). l'uso di "grep -Hni" impone che il nome del file venga visualizzato su ogni riga
gabor

Grazie per aver fornito l'unica risposta che ha funzionato per i sistemi che sono così croccanti, senza grep --exclude-dir, ma su cui bisogna ancora lavorare
Dmitri DB

2

Ecco un esempio completo da uno script in uno dei miei progetti che potrebbe aiutare, chiamo questo file "all_source" (contrassegnato come eseguibile) e lo metto nella directory principale del mio progetto, quindi lo chiamo come grep myfunc $(./all_source)l'ordinamento alla fine dello script è totalmente opzionale.

#!/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

Questo script restituisce tutti i nomi di file nel progetto corrispondenti *.h, *.cpp, *.c, *.lua, *.*awk, ma non cerca in tutte le cartelle denominate .svn e cartelle gen oltre a saltare le cartelle per ./libe ./vc6(ma solo quelle subito dalla radice del progetto). Quindi quando lo fai grep myfunc $(./all_source)greps solo in quei file. Dovrai chiamarlo anche dalla directory principale del progetto.


0

C'è anche l'opzione -prune per trovare:

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

0

Puoi provare a fare questo:

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

Ad esempio: se non si desidera cercare il contenuto nei file di registro, effettuare le seguenti operazioni:

grep -R "myfunc" . | grep -v log/
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.