Quando voglio cercare un intero albero per alcuni contenuti, uso
find . -type f -print0 | xargs -0 grep <search_string>
C'è un modo migliore per farlo in termini di prestazioni o brevità?
Quando voglio cercare un intero albero per alcuni contenuti, uso
find . -type f -print0 | xargs -0 grep <search_string>
C'è un modo migliore per farlo in termini di prestazioni o brevità?
Risposte:
Controlla se la tua opzione di grepsupporto -r(per il recurse )
grep -r <search_string> .
--exclude-dirper affrontare le prestazioni e abbiamo un vincitore!
grepnelle recenti distribuzioni FreeBSD e Linux lo supportano. E perchè --exclude-dir? Non hai chiesto di cercare un intero albero ?
--exclude-dirè effettivamente utile nel mio caso d'uso (perché parti del sottostruttura sono grandi, ma inutili) e ho chiesto informazioni sulle prestazioni ... ma hai ragione, non è necessario.
--exclude-dirè esclusivo di GNU grep. (-:
Una risposta subottimale: anziché eseguire il piping dell'output di findinto grep, è possibile eseguire
find . -type f -exec grep 'research' {} '+'
e voilà, un comando invece di due!
spiegazione :
find . -type f
trova tutti i file regolari all'interno.
-exec grep 'research'
grep "ricerca"
{}
nel nome file trovato
'+'
usa un comando per tutti i nomi di file, non una volta per nome file.
Nb: con ';'esso sarebbe stato una volta per nome file.
A parte questo, se lo usi per elaborare il codice sorgente, puoi esaminare ackquale è fatto per cercare facilmente i bit di codice.
Modificare :
Puoi estendere un po 'quella ricerca. Innanzitutto, è possibile utilizzare l' opzione -name ''di findper cercare i file con un modello di denominazione specifico.
Per esempio :
solo i file che corrispondono ai registri: -name '*.log'
solo i file che corrispondono alle intestazioni c, ma non è possibile utilizzare maiuscole o minuscole per le estensioni dei nomi: -iname *.c
Nb: come per grepe ack, l' -iinterruttore significa maiuscole e minuscole in questo caso.
In tal caso, grep verrà visualizzato senza colore e senza numeri di riga.
Si può cambiare la situazione con l' --colorei -ninterruttori (numeri di colore e linee in file, rispettivamente).
Alla fine, puoi avere qualcosa del tipo:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
per esempio
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
-name '*.log'È più veloce.
Se vuoi rientrare nelle sottodirectory:
grep -R 'pattern' .
L' -Ropzione non è un'opzione standard, ma è supportata dalle grepimplementazioni più comuni .
-rinvece di -Rsaltare i collegamenti simbolici quando GNU grep è interessato
grepimplementazioni GNU catturano ricorsioni, penso. Altrimenti dipende da cosa intendi per "albero".
grepdovrebbe fare. Se l'utente ha anelli simbolici nella struttura della directory, beh, questo è il problema dell'utente :-)
/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...(-XI come strumenti che mi fanno da babysitter (a meno che non forniscano strana magia che chiamano "AI"). (-;
Come notato sopra -ro -R(a seconda della gestione dei collegamenti simbolici desiderata) è un'opzione rapida.
Tuttavia -d <action>a volte può essere utile.
La cosa bella -dè il comando skip, che mette a tacere "grep: nome_directory: è una directory" quando si desidera solo scansionare il livello corrente.
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
ed ovviamente:
$ grep -d recurse foo *
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).
$
L' -d skipopzione è DAVVERO utile all'interno di un altro script, quindi non è necessario 2> /dev/null. :)
Se hai a che fare con molti file, grep viene eseguito più velocemente se elimini i file di cui ha bisogno per cercare invece di eseguire il grepping di tutti i file nelle sottocartelle.
Uso questo formato a volte:
grep "primary" `find . | grep cpp$`
Trova tutti i file nelle sottocartelle .che terminano in cpp. Quindi grep quei file per "primario".
Se lo desideri, puoi continuare a convogliare questi risultati in ulteriori chiamate grep:
grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"