grep, mas apenas determinadas extensões de arquivo


966

Estou trabalhando para escrever alguns scripts em grepdeterminados diretórios, mas esses diretórios contêm todos os tipos de tipos de arquivos.

Eu quero grepapenas .he .cpppor enquanto, mas talvez alguns outros no futuro.

Até agora eu tenho:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP email@domain.com

Alguém pode me mostrar como eu adicionaria agora apenas as extensões de arquivo específicas?


13
Tentou grep -r -i CP_Image ~/path1/*.{h,cpp}?

8
Use The Silver Searcher : ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com. Tarefa concluída.
9789 Johnsyweb


Use o egrep (provavelmente está pré-instalado no seu sistema) e, em seguida, você pode usar um regex.
Dogweather

8
Os caras GNU realmente confuso quando adicionado -rpara greptê-lo procurar arquivos como que quebra o mantra UNIX de ter ferramentas que "fazer uma coisa e fazê-lo bem". Existe uma ferramenta perfeitamente boa para encontrar arquivos com um nome MUITO óbvio.
Ed Morton

Respostas:


1354

Basta usar o --includeparâmetro, assim:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

isso deve fazer o que você quer.

Para tirar a explicação da resposta do HoldOffHunger abaixo:

  • grep: comando

  • -r: recursivamente

  • -i: ignorar caso

  • --include \*.cpp: all * .cpp: arquivos C ++ (escape com \ apenas no caso de você ter um diretório com asteriscos nos nomes dos arquivos)

  • ./: Inicia no diretório atual.


123
Para o registro: -r (recursiva) -i (ignorar maiúsculas e minúsculas) --include (pesquise apenas arquivos que correspondam ao padrão)
Luis

34
Pode ser otimizado ainda mais paragrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol

1
@Hong, onde está a documentação que -R é para links simbólicos?
titus

8
Este exemplo parece ter uma pontuação alta porque abrange uma gama tão ampla de possibilidades, mas a resposta dada abaixo de grep -r --include = *. Txt 'searchterm' ./ realmente explica a essência da resposta
David Casper

10
por que não usar aspas duplas em vez de barra invertida? por exemplo:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda

283

Algumas dessas respostas pareciam muito sintáticas ou produziam problemas no meu servidor Debian. Isso funcionou perfeitamente para mim:

Revolução do PHP: Como Grep arquivos no Linux, mas apenas determinadas extensões de arquivo?

Nomeadamente:

grep -r --include=\*.txt 'searchterm' ./

... ou versão sem distinção entre maiúsculas e minúsculas ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: comando

  • -r: recursivamente

  • -i: ignorar caso

  • --include: all * .txt: arquivos de texto (escape com \ apenas no caso de você ter um diretório com asteriscos nos nomes dos arquivos)

  • 'searchterm': O que pesquisar

  • ./: Inicia no diretório atual.


7
Você deve escapar do *uso \*.cppou '*.cpp'. Caso contrário, ele não fornecerá o resultado esperado quando o diretório de trabalho contiver alguns *.txtarquivos.
Melebius

@Melebius, você pode explicar por que precisa escapar - isso tem alguma coisa a ver com as extensões CPP ou TXT que você mencionou? Ou você acabou de usá-los como exemplos?
Simon Médio

2
@SimonEast Essas extensões são aquelas usadas nesta pergunta e resposta, nada de especial em contrário. Provavelmente funcionaria sem escapar ao usar, --include=<pattern>mas é importante escapar *com --include <pattern>(um espaço em vez de =) que parece muito semelhante caso contrário.
Melebius

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn "alguma coisa para grep" --include = *. {module, inc, c, h} *
ashish

3
Boa resposta. Mais limpo do que o aceito em IMO, mas você deve adicionar critérios de pesquisa como @ashish observou
billynoah

por que --includeopção após agulha e não com outras opções?
precisa saber é o seguinte

@vladkras, o que você quer dizer com agulha? É isso --?
heretoinfinity

50

E se:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print

5
eu sugeriria agrupar esses -nameargumentos. coisas estranhas podem acontecer se você não. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
Nullrevolution

use com "-type f" adicional para ignorar todos os objetos de diretório, apenas interessados ​​em arquivos.
kensai

1
Eu usei esse método por anos e funciona, mas é muito mais lento que o grep recursivo, pois o exec do find gera um processo grep separado para cada arquivo a ser pesquisado.
Beaudet

Ao abordar o comentário de @ beaudet, é findpossível agrupar argumentos opcionalmente, reduzindo ao mínimo as invocações do processo chamado. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Isso é sugerido, mas não destacado na resposta do @ fedorqui abaixo e é uma melhoria que vale a pena. O -Hargumento para grep aqui é útil quando localizar apenas identifica um único arquivo correspondente. Isso poderia eliminar o uso de -printna resposta. Se sua lista total de arquivos for suficientemente pequena, {path1,path2}/**/*.{cpp,h}pode ser preferível usar um globo recursivo do shell (por exemplo ).
Malcolm

19

Não há opção -r nos servidores HP e Sun, dessa maneira funcionou para mim no meu servidor HP

find . -name "*.c" | xargs grep -i "my great text"

-i é para pesquisa sem distinção entre maiúsculas e minúsculas


1
Encontrei vários servidores para empresas de hospedagem na web que não têm a opção --include disponível para o fgrep e esta é a linha de comando que eu uso nessas instâncias.
Borgboy

A opção --include também não está disponível ao usar o Git for Windows (MinGW / MSys).
Darren Lewis

O @DarrenLew está disponível no Git Bash para Windows. Mas, estranhamente, ele adiciona aliases coloridos como, llmas não adiciona --color=autoao grep.
Xeverous

Essa deve ser a resposta aceita para integridade, portabilidade e brevidade!
Grant Foster

12

Como se trata de encontrar arquivos, vamos usar find!

Usando o GNU find, você pode usar a -regexopção para encontrar esses arquivos na árvore de diretórios cuja extensão é .hou .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Então, é apenas uma questão de executar grepem cada um de seus resultados:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Se você não tiver essa distribuição de localização, precisará usar uma abordagem como a de Amir Afghani , usando -opara concatenar opções ( o nome está terminando com .hou com.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

E se você realmente deseja usar grep, siga a sintaxe indicada para --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^

7

A maneira mais fácil é

find . -type  f -name '*.extension' | xargs grep -i string 

3

ag (o pesquisador prateado) possui uma sintaxe bastante simples para esse

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

tão

ag -G *.h -G *.cpp CP_Image <path>

usando ag 2.2.0, eu precisava colocar minhas bandeiras por último:ag _string_to_find_ -G _filename_regex_
ryanrain 20/04

3

A resposta abaixo é boa:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Mas pode ser atualizado para:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com

O que pode ser mais simples.


1

Deve escrever "-exec grep" para cada "-o -name"

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

Ou agrupe-os por ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

a opção '-Hn' mostra o nome e a linha do arquivo.


1

Estou ciente de que esta questão é um pouco antiga, mas gostaria de compartilhar o método que normalmente uso para encontrar arquivos .c e .h :

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

ou se você também precisar do número da linha:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.