Respostas:
Bem, o caso genérico que funciona com qualquer comando que grava no stdout é usar xargs
, o que permitirá anexar qualquer número de argumentos da linha de comando ao final de um comando:
$ find … | xargs grep 'search'
Ou para incorporar o comando na sua grep
linha com backticks ou $()
, que executará o comando e substituirá sua saída:
$ grep 'search' $(find …)
Observe que esses comandos não funcionam se os nomes dos arquivos contiverem espaços em branco ou certos outros "caracteres estranhos" ( \'"
para xargs, \[*?
para $(find …)
).
No entanto, no caso específico da find
capacidade de executar um programa nos argumentos fornecidos, está embutido:
$ find … -exec grep 'search' {} \;
Tudo entre -exec
e ;
é o comando a ser executado; {}
é substituído pelo nome do arquivo encontrado por find
. Isso executará um separado grep
para cada arquivo; como grep
pode pegar muitos nomes de arquivos e pesquisar em todos, você pode alterar ;
para +
to tell find para passar todos os nomes de arquivos correspondentes de grep
uma só vez:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Embora -exec +
seja muito eficiente, ele não existe em todas as versões do find.
$ find … -exec grep 'search' {} \+
formulário é muito mais rápido.
Algumas versões grep
(por exemplo, no Linux, BSD ou Mac OS X não incorporado ) têm uma -r
opção para fazer uma pesquisa recursiva. No OpenBSD, use -R
(e não há --exclude
como no exemplo abaixo). Isso abrange combinações simples de find
com grep
.
Se sua implementação não possui o -R
sinalizador ou se você deseja critérios de correspondência de arquivo mais sofisticados, use o -exec
principal de find
para executá-lo grep
. Algumas find
implementações mais antigas não suportam -exec
… +
; nesses sistemas, use um em ;
vez de +
(isso será chamado grep
uma vez por arquivo, portanto será mais lento, mas, caso contrário, o resultado será o mesmo). Observe o /dev/null
truque para grep
mostrar o nome do arquivo, mesmo que seja chamado em um único arquivo (o GNU grep e o FreeBSD / NetBSD / OSX grep têm uma -H
opção para obter o mesmo efeito).
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
tem -H
opção para sempre imprimir o nome do arquivo.