Verifique se a sua opção grep
suporta -r
(para recurse ):
grep -r <search_string> .
Quando eu quero pesquisar uma árvore inteira por algum conteúdo, eu uso
find . -type f -print0 | xargs -0 grep <search_string>
Existe uma maneira melhor de fazer isso em termos de desempenho ou brevidade?
Se você quiser recorrer aos subdiretórios:
grep -R 'pattern' .
A opção -R
não é uma opção padrão, mas é suportada pelas implementações mais comuns de grep
.
Uma resposta ótima:
Em vez de canalizar a saída de find
para grep
, você poderia simplesmente executar
find . -type f -exec grep 'research' {} '+'
e voila, um comando em vez de dois!
explicação:
find . -type f
encontre todos os arquivos regulares em.
-exec grep 'research'
grep 'research'
{}
no nome do arquivo encontrado
'+'
use um comando para todos os nomes de arquivos, não uma vez por nome de arquivo.
Nb: com ';'
teria sido uma vez por nome de arquivo.
Além disso, se você usar isso para processar o código-fonte, poderá procurar em ack
, que é feito para procurar bits de código facilmente.
Editar:
Você pode estender essa pesquisa um pouco. Primeiro, você pode usar a opção -name ''
de find
para procurar arquivos com o padrão de nomenclatura specifig.
Por exemplo:
apenas arquivos que correspondem a registros: -name '*.log'
apenas arquivos que correspondem aos cabeçalhos c, mas você não pode ficar com maiúsculas ou minúsculas nas extensões de nome de arquivo: -iname *.c
Nb: como para grep
e ack
, a opção -i
não diferencia maiúsculas de minúsculas neste caso.
Nesse caso, o grep será exibido sem cor e sem números de linha.
Você pode alterar isso com as opções --color
e -n
(números de cor e linhas nos arquivos, respectivamente).
No final, você pode ter algo como:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
por exemplo
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
Como mencionado acima, -r
ou -R
(dependendo do tratamento desejado do symlink) é uma opção rápida.
No entanto, -d <action>
pode ser útil às vezes.
O interessante sobre -d
é o comando skip, que silencia o "grep:
directory_name: É um diretório "quando você quer apenas varrer o nível atual.
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
e claro:
$ 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).
$
A opção -d skip
é realmente útil em outro script, portanto, você não precisa 2> /dev/null
. :)
Se você está lidando com muitos arquivos, o grep roda mais rápido se você remover os arquivos que precisa pesquisar em vez de copiar todos os arquivos em subpastas.
Eu uso este formato às vezes:
grep "primary" 'find . | grep cpp$'
Encontre todos os arquivos nas subpastas de .
que terminam em cpp
. Então grep esses arquivos para "primário".
Se você quiser, pode manter os resultados em outras chamadas do grep:
grep "primary" 'find . | grep cpp$' | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"