Como posso usar o grep para pesquisar vários diretórios não aninhados?

21

Pode parecer que estou fazendo a mesma coisa que esta pergunta , mas tenho requisitos diferentes. Este é um exemplo do meu sistema de arquivos:

  • /código/
    • interno/
      • dev /
      • a Principal/
    • público/
      • dev /
      • a Principal/
      • liberação/
    • Ferramentas/

/code/internal/dev/, /code/public/dev/E /code/tools/conter subdirectórios para múltiplos projectos. Eu trabalho quase exclusivamente nas ramificações de desenvolvimento de /code/internal/e /code/public/, e geralmente desejo pesquisar uma sequência de texto nesses diretórios junto com /code/tools/(que não possui ramificações). Nesses casos, tenho que executar três comandos separados:

$ grep -r "some string" /code/internal/dev/
$ grep -r "some string" /code/public/dev/
$ grep -r "some string" /code/tools/

Eu gostaria de saber se existe um único comando para fazer isso. Caso contrário, eu provavelmente precisaria escrever um script bash simples.

David Kennedy
fonte

Respostas:

38

Você pode concatenar vários caminhos para o grep procurar:

grep -r "some string" /code/internal/dev/ /code/public/dev/ /code/tools/
Artur Szymczak
fonte
Isto é tão óbvio. Por que eu não pensei nisso ?!
David Kennedy
Na verdade, isso gera um erro, a grep: /code/internal/dev/*.cs: No such file or directorymenos que eu remova *.cso comando. A culpa é minha, porque eu coloquei a *.cspergunta originalmente.
19420 David Kennedy
14

Se você deseja fazer o máximo uso de curingas (e a hierarquia que você postou estiver completa), você pode

grep -r "some string" /code/{*/dev,tools}/*.cs

Explicação:

O primeiro passo é a expansão da lista entre chaves. foo{bar,baz}quxexpande para foobarqux foobazqux. Ou seja, há uma palavra separada gerada para cada item separado por vírgula na lista, com a parte do prefixo e do postfix anexada a cada um. Você pode ver como isso funciona, fazendo

echo A{1,2,3,4}B

quais saídas

A1B A2B A3B A4B

Observe que isso também funciona com vários chavetas e também com argumentos vazios; por exemplo

echo {,1,2}{0,1,2}:{2,3}

0:2 0:3 1:2 1:3 2:2 2:3 10:2 10:3 11:2 11:3 12:2 12:3 20:2 20:3 21:2 21:3 22:2 22:3

Portanto, após a expansão da chave, seu comando fica assim:

grep -r "some string" /code/*/dev/*.cs /code/tools/*.cs

O próximo passo é a expansão de caracteres curinga. Você já sabe disso *.cs, mas também funciona para diretórios intermediários; além disso, se /segue, apenas os diretórios são correspondidos. Portanto, dada sua hierarquia (e criando nomes de .csarquivos), você obterá o comando:

grep -r "some string" /code/internal/dev/file1.cs /code/internal/dev/file2.cs /code/public/dev/file3.cs /code/tools/file4.cs /code/tools/file5.cs

Somente depois que tudo isso aconteceu, grepé chamado com esta lista de argumentos (observe que o mesmo acontece com seus comandos originais; grepnunca chega a ver a *; expansão que é completamente feita bashantes de chamar grep).

celtschk
fonte