Risposte:
Bene, il caso generico che funziona con qualsiasi comando che scrive su stdout è da usare xargs
, che ti permetterà di allegare un numero qualsiasi di argomenti della riga di comando alla fine di un comando:
$ find … | xargs grep 'search'
O per incorporare il comando nella tua grep
riga con backtick o $()
, che eseguirà il comando e sostituirà il suo output:
$ grep 'search' $(find …)
Si noti che questi comandi non funzionano se i nomi dei file contengono spazi bianchi o altri "caratteri strani" ( \'"
per xargs, \[*?
per $(find …)
).
Tuttavia, nel caso specifico della find
possibilità di eseguire un programma su determinati argomenti è incorporato:
$ find … -exec grep 'search' {} \;
Tutto tra -exec
e ;
è il comando da eseguire; {}
viene sostituito con il nome file trovato da find
. Quello eseguirà un separato grep
per ogni file; poiché grep
può prendere molti nomi di file e cercarli tutti, puoi cambiare ;
in +
per dire a find di passare contemporaneamente tutti i nomi di file corrispondenti grep
:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Sebbene -exec +
sia molto efficiente, non esiste su tutte le versioni di find.
$ find … -exec grep 'search' {} \+
modulo sia molto più veloce.
Alcune versioni di grep
(ad esempio su Linux non incorporato o BSD o Mac OS X) hanno -r
un'opzione per effettuare una ricerca ricorsiva. Su OpenBSD, usa -R
(e non c'è --exclude
come nell'esempio sotto). Questo copre semplici combinazioni di find
con grep
.
Se l'implementazione non ha il -R
flag o se si desidera criteri di corrispondenza dei file più elaborati, è possibile utilizzare il -exec
primario di find
per eseguirlo grep
. Alcune find
implementazioni precedenti non supportano -exec
... +
; su questi sistemi, usa un ;
invece di +
(questo chiamerà grep
una volta per file, quindi sarà più lento, ma altrimenti il risultato sarà lo stesso). Nota il /dev/null
trucco che induce grep
a mostrare il nome del file anche se viene chiamato su un singolo file (GNU grep e FreeBSD / NetBSD / OSX grep hanno -H
un'opzione per ottenere lo stesso effetto).
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
ha l' -H
opzione per stampare sempre il nome file.