Come faccio a passare un elenco di file a grep


98

Sto usando finde ricevendo un elenco di file che voglio greppassare. Come convoglio l'elenco a grep?

Risposte:


116

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 grepriga 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 findpossibilità di eseguire un programma su determinati argomenti è incorporato:

$ find … -exec grep 'search' {} \;

Tutto tra -exece ;è il comando da eseguire; {}viene sostituito con il nome file trovato da find. Quello eseguirà un separato grepper ogni file; poiché greppuò 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' {} \+

1
Va notato che le prime due forme non funzionano con nomi di file contenenti spazi.
enzotib,

1
Io preferisco find ... -type f -print0 | xargs -r0 grep 'search' /dev/null. QED. Sebbene -exec +sia molto efficiente, non esiste su tutte le versioni di find.
Arcege,

Purtroppo non riesco a controllarti correttamente 3 volte.
Arcabard,

3
Suggerisco di usare il -exec, piuttosto che il xargs. Se usi -execin find, creerà solo una shell per grep per il contenuto. Se usi il xargs, creerà due shell: una per il finde l'altra per il xargs.

2
per esperimento trovo che il $ find … -exec grep 'search' {} \+modulo sia molto più veloce.
gogoud,

9

Alcune versioni di grep(ad esempio su Linux non incorporato o BSD o Mac OS X) hanno -run'opzione per effettuare una ricerca ricorsiva. Su OpenBSD, usa -R(e non c'è --excludecome nell'esempio sotto). Questo copre semplici combinazioni di findcon grep.

Se l'implementazione non ha il -Rflag o se si desidera criteri di corrispondenza dei file più elaborati, è possibile utilizzare il -execprimario di findper eseguirlo grep. Alcune findimplementazioni precedenti non supportano -exec... +; su questi sistemi, usa un ;invece di +(questo chiamerà grepuna volta per file, quindi sarà più lento, ma altrimenti il ​​risultato sarà lo stesso). Nota il /dev/nulltrucco che induce grepa mostrare il nome del file anche se viene chiamato su un singolo file (GNU grep e FreeBSD / NetBSD / OSX grep hanno -Hun'opzione per ottenere lo stesso effetto).

find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .

2
GNU grepha l' -Hopzione per stampare sempre il nome file.
enzotib,
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.