Používám find
a získám seznam souborů, které chci grep
through. Jak mohu dát tento seznam kanálu grep
?
Obecným případem, který pracuje s jakýmkoli příkazem, který píše do stdout, je použití xargs
, které vám umožní připojit ke konci příkazu libovolný počet argumentů z příkazového řádku:
$ find … | xargs grep 'search'
Nebo vložte příkaz do řádku grep
pomocí backticks nebo $()
, které příkaz spustí a nahradí jeho výstup:
$ grep 'search' $(find …)
Tyto příkazy nefungují, pokud názvy souborů obsahují mezeru nebo určité jiné „divné znaky“ (\'"
Pro xargs, \[*?
Pro $(find …)
).
Ve specifickém případě find
je však zabudována schopnost provádět program na zadaných argumentech:
$ find … -exec grep 'search' {} \;
Všechno mezi -exec
A ;
Je příkaz k provedení; {}
Je nahrazen názvem souboru nalezeným find
. Tím se provede samostatný grep
pro každý soubor; protože grep
může mít mnoho názvů souborů a prohledávat je všechny, můžete změnit ;
na +
, abyste zjistili, že všechny odpovídající názvy souborů předáte grep
na jednou:
$ find … -exec grep 'search' {} \+
Některé verze grep
(např. Na non-embedded Linux nebo BSD nebo Mac OS X) mají možnost -r
provést rekurzivní vyhledávání. Na OpenBSD použijte -R
(a neexistuje žádný --exclude
jako v příkladu níže). To zahrnuje jednoduché kombinace find
s grep
.
Pokud vaše implementace nemá příznak -R
, nebo pokud chcete splnit kritéria pro porovnávání souborů s fanoušky, můžete použít -exec
primární z find
, aby bylo provedeno grep
. Několik starších implementací find
nepodporuje -exec
… +
; v těchto systémech použijte ;
namísto +
(toto zavolá grep
jednou na soubor, takže to bude pomalejší, jinak bude výsledek stejný). Všimněte si triku /dev/null
, který způsobí, že grep
zobrazí název souboru, i když se stane, že bude vyvolán na jediném souboru (GNU grep a FreeBSD/NetBSD/OSX grep mají -H
možnost dosáhnout stejného účinku).
find . -type f -name '*.o' -Prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .