Como posso “grep” filtrar recursivamente o nome dos arquivos que quero com curingas?


40

Quando eu quero executar uma pesquisa grep recursiva no diretório atual, geralmente:

grep -ir "string" .

Mas esse comando pesquisa dentro de todos os tipos de arquivos, incluindo arquivos binários (fotos, áudio, vídeo, etc ...), o que resulta em um processo de pesquisa muito lento.

Se eu fizer isso, por exemplo, não funciona:

grep -ir "string" *.php

Não funciona porque não há arquivos PHP dentro do diretório atual, mas dentro de alguns subdiretórios do diretório atual, e os nomes dos subdiretórios não terminam com ".php", para que o grep não os procure.

Então, como posso fazer uma pesquisa recursiva no diretório atual, mas também especificando curingas de nome de arquivo? (ou seja: pesquise apenas arquivos que terminam em uma extensão específica)

Respostas:


58

Use grepa --includeopção:

grep -ir "string" --include="*.php" .

1
Ok, parece que minha versão do grep era antiga, porque não tinha essa opção (não é de admirar por que não consegui descobrir como fazer isso!). Recebi a mensagem: "grep: opção não reconhecida` --include = *. Php '". Mas acabei de atualizar para um mais novo e agora funciona. Obrigado!
OMA

Eu tive que substituir o período no final e usar:grep -ir "string" --include="*.php" *
Stuart

Eu pensei que o período fosse apenas o fim da linha! Eu não usei ou precisei.
boardtc

14

Se você possui uma versão grepque não possui a --includeopção, pode usar o seguinte. Ambos foram testados em uma estrutura de diretórios como esta:

$ tree
.
├── a
├── b
   └── foo2.php
├── c
   └── d
       └── e
           └── f
               └── g
                   └── h
                       └── foo.php
├── foo1.php
└── foo.php

Onde todos os .phparquivos contêm a sequência string.

  1. Usar find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string

    Explicação

    Isso encontrará todos os .phparquivos e, em seguida, será executado grep -H stringem cada um deles. Com finda -execopção, {}é substituído por cada um dos arquivos encontrados. O -Hdiz greppara imprimir o nome do arquivo, bem como a linha correspondente.

  2. Supondo que você tenha uma versão nova o suficiente bash, use globstar:

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string

    Explicação

    Conforme explicado no manual do bash :

    globstar

    Se definido, o padrão '**' usado em um contexto de expansão de nome de arquivo corresponderá a todos os arquivos e zero ou mais diretórios e subdiretórios. Se o padrão for seguido por um '/', apenas diretórios e subdiretórios corresponderão.

    Portanto, ao executar, shopt -s globstarvocê está ativando o recurso e a globstaropção do Bash, que faz a **/*phpexpansão para todos os .phparquivos no diretório atual ( **corresponde a 0 ou mais diretórios, portanto, também **/*phpcorresponde ./foo.php) aos quais eles são recebidos string.


-2

Usar */*.php

Isso torna o grep search um nível de subdiretório


Algo deu errado quando asteriscos e pontos desapareceram.
Dennis Nolan

Você pode usar backticks para formatar o código e evitar ambigüidades sobre o uso de asteriscos para enfatizar a formatação de markdown. PS observe que a pergunta é feita sobre "pesquisa recursiva" no parágrafo final (embora não seja meu voto negativo).
RedGrittyBrick

Não é uma resposta correta, porque é bom apenas para estruturas de diretório profundas de um nível, como você mencionou, mas ainda assim é bom saber;). Meu voto positivo por isso.
OMA
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.