adicione um comentário --exclude-dirpara abordar o desempenho e temos um vencedor!
Dancrumb
1
Apenas observe que isso não é portátil, no entanto, grepnas recentes distribuições do FreeBSD e Linux o suportam. E por que --exclude-dir? Você não pediu para procurar uma árvore inteira ?
Philippos
Ponto justo ... --exclude-diré realmente útil no meu caso de uso (porque partes da subárvore são grandes, mas inúteis) e perguntei sobre desempenho ... mas você está certo, não é necessário.
Dancrumb
Nesse caso, devo acrescentar que o IIRC --exclude-diré exclusivo do GNU grep. (-:
Philippos
13
Uma resposta subótima: em vez de canalizar a saída para findinto grep, você pode 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 dentro.
-exec grep 'research'
grep 'pesquisa'
{}
no nome do arquivo encontrado
'+'
use um comando por todos os nomes de arquivos, não uma vez por nome de arquivo.
Nota: com ';'isso teria sido uma vez por nome de arquivo.
Fora isso, se você usar isso para processar o código-fonte, poderá pesquisar o ackque é feito para procurar bits de código facilmente.
Você pode estender um pouco essa pesquisa. Primeiro, você pode usar a -name ''opção de findpara procurar arquivos com padrão de nomeação específico.
Por exemplo :
somente arquivos que correspondem aos logs: -name '*.log'
apenas arquivos que correspondem aos cabeçalhos c, mas você não pode usar letras maiúsculas ou minúsculas nas extensões do seu nome de arquivo: -iname *.c
Nota: como para grepe ack, a -iopção significa insensível a maiúsculas e minúsculas neste caso.
Nesse caso, o grep será exibido sem cor e sem números de linha.
Você pode mudar isso com o --colore os -ninterruptores (números de cor e de linhas em arquivos respectivamente).
acké grande, e uma versão mais rápida acké ag(o pesquisador prata, geoff.greer.fm/ag )
cfeduke
1
Eu prefiro isso com filtro como -name '*.log'é mais rápido.
Sdkks
@cfeduke eu não tentei, principalmente porque ag não é parte de repositórios apt padrão em WSL (você tem que trabalhar com o que você tem!)
Pierre-Antoine Guillaume
Um truque é adicionar / dev / null ao grep para que o nome do arquivo apareça.
ChuckCottrill 18/08/19
Um truque é procurar apenas diretórios e, em seguida, -exec grep / dev / null {} / * para obter todos os arquivos com um único fork / exec por diretório.
ChuckCottrill 18/08/19
12
Se você deseja recursar em subdiretórios:
grep -R 'pattern' .
A -Ropção não é uma opção padrão, mas é suportada pelas grepimplementações mais comuns .
Use -rem vez de -Rpular ligações simbólicas ao GNU grep está em questão
αғsнιη
1
@AFSHIN Por que você não gostaria de seguir links simbólicos?
Kusalananda
4
Recursão @Kusalananda? Embora as grepimplementações atuais do GNU capturem recursões, eu acho. Caso contrário, depende do que você quer dizer com "árvore".
Philippos
2
@ Phipippos IMHO, cuidar do usuário não é algo que uma ferramenta como grepdeve fazer. Se o usuário tem laços link simbólico em sua estrutura de diretório, bem, isso é problema do usuário :-)
Kusalananda
3
@Kusalananda E se o sistema forneceu o loop? Nunca me perdi em /sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...(-XI como ferramentas de babá para mim (a menos que elas forneçam magia estranha que chamam de "AI"). (-;
Philippos
5
Como observado acima, -rou -R(dependendo do tratamento do link simbólico desejado) é uma opção rápida.
No entanto, -d <action>pode ser útil às vezes.
O interessante -dé o comando skip, que silencia o "grep: directory_name: Is a directory" quando você deseja apenas verificar 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 -d skipopção é REALMENTE útil dentro de outro script para que você não precise 2> /dev/null. :)
Se você estiver lidando com muitos arquivos, o grep será executado mais rapidamente se você remover os arquivos que eles precisam pesquisar, em vez de grep todos os arquivos em subpastas.
Eu uso esse formato algumas vezes:
grep "primary" `find . | grep cpp$`
Encontre todos os arquivos nas subpastas .desse fim em cpp. Em seguida, grep esses arquivos para "primário".
Se desejar, você pode continuar canalizando esses resultados para outras chamadas grep:
backtics não são uma boa prática moderna, eles são todos, mas obsoleto
Christopher
1
Isso será interrompido se você tiver arquivos com caracteres especiais em seus nomes. Eu não sei o quão especial elas precisam ser para serem especiais demais para que isso funcione como está, mas o que você está fazendo é realmente a mesma coisa que analisar a saída de ls, o que também é ruim.
Respostas:
Verifique se a sua opção de
grep
suporte-r
(para recursão ):fonte
--exclude-dir
para abordar o desempenho e temos um vencedor!grep
nas recentes distribuições do FreeBSD e Linux o suportam. E por que--exclude-dir
? Você não pediu para procurar uma árvore inteira ?--exclude-dir
é realmente útil no meu caso de uso (porque partes da subárvore são grandes, mas inúteis) e perguntei sobre desempenho ... mas você está certo, não é necessário.--exclude-dir
é exclusivo do GNUgrep
. (-:Uma resposta subótima: em vez de canalizar a saída para
find
intogrep
, você pode simplesmente executare voila, um comando em vez de dois!
explicação:
encontre todos os arquivos regulares dentro.
grep 'pesquisa'
no nome do arquivo encontrado
use um comando por todos os nomes de arquivos, não uma vez por nome de arquivo.
Nota: com
';'
isso teria sido uma vez por nome de arquivo.Fora isso, se você usar isso para processar o código-fonte, poderá pesquisar o
ack
que é feito para procurar bits de código facilmente.ack
Editar:
Você pode estender um pouco essa pesquisa. Primeiro, você pode usar a
-name ''
opção defind
para procurar arquivos com padrão de nomeação específico.Por exemplo :
somente arquivos que correspondem aos logs:
-name '*.log'
apenas arquivos que correspondem aos cabeçalhos c, mas você não pode usar letras maiúsculas ou minúsculas nas extensões do seu nome de arquivo:
-iname *.c
Nota: como para
grep
eack
, a-i
opção significa insensível a maiúsculas e minúsculas neste caso.Nesse caso, o grep será exibido sem cor e sem números de linha.
Você pode mudar isso com o
--color
e os-n
interruptores (números de cor e de linhas em arquivos respectivamente).No final, você pode ter algo como:
por exemplo
fonte
ack
é grande, e uma versão mais rápidaack
éag
(o pesquisador prata, geoff.greer.fm/ag )-name '*.log'
é mais rápido.Se você deseja recursar em subdiretórios:
A
-R
opção não é uma opção padrão, mas é suportada pelasgrep
implementações mais comuns .fonte
-r
em vez de-R
pular ligações simbólicas ao GNU grep está em questãogrep
implementações atuais do GNU capturem recursões, eu acho. Caso contrário, depende do que você quer dizer com "árvore".grep
deve fazer. Se o usuário tem laços link simbólico em sua estrutura de diretório, bem, isso é problema do usuário :-)/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...
(-XI como ferramentas de babá para mim (a menos que elas forneçam magia estranha que chamam de "AI"). (-;Como observado acima,
-r
ou-R
(dependendo do tratamento do link simbólico desejado) é uma opção rápida.No entanto,
-d <action>
pode ser útil às vezes.O interessante
-d
é o comando skip, que silencia o "grep: directory_name: Is a directory" quando você deseja apenas verificar o nível atual.e claro:
A
-d skip
opção é REALMENTE útil dentro de outro script para que você não precise2> /dev/null
. :)fonte
Se você estiver lidando com muitos arquivos, o grep será executado mais rapidamente se você remover os arquivos que eles precisam pesquisar, em vez de grep todos os arquivos em subpastas.
Eu uso esse formato algumas vezes:
Encontre todos os arquivos nas subpastas
.
desse fim emcpp
. Em seguida, grep esses arquivos para "primário".Se desejar, você pode continuar canalizando esses resultados para outras chamadas grep:
fonte