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 protected]

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

Jason
fonte
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 protected]. 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 protected]

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.

Nelson
fonte
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.

HoldOffHunger
fonte
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} ./
Yuri Malov
fonte
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
Amir Afghani
fonte
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

Sam B
fonte
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}
#                      ^^^^^^^^^^^^^^^^^^^
fedorqui 'Então pare de prejudicar'
fonte
7

A maneira mais fácil é

find . -type  f -name '*.extension' | xargs grep -i string 
user3640130
fonte
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>
Eldamir
fonte
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 protected]

Mas pode ser atualizado para:

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

O que pode ser mais simples.

hao
fonte
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.

where23
fonte
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"
Tom
fonte