Como encontrar arquivos com texto específico dentro e extensão específica?

4

No UNIX: nas pastas existem arquivos com extensão .sas (programas) e arquivos com .sas7bdat (tabelas). Eu preciso encontrar programas (e não tabelas) que contenham o texto "liasse". Eu tentei lançando este comando:

grep -rli liasse *.sas ./

No resultado, posso ver o nome de uma tabela. Qual deve ser o comando para recuperar apenas programas?

    
por Nasser 11.01.2018 / 09:26

3 respostas

2

Este é um comando compatível com POSIX que inicia grep para muitos arquivos de uma só vez:

find . -type f -name '*.sas' -exec grep -li liasse {} +

Seu comando grep -rli liasse *.sas ./ não funciona como esperado. Vamos analisar o que acontece:

  1. *.sas sofre globulação de concha.
    1. Se houver pelo menos um objeto no diretório atual que corresponda a *.sas , todos eles serão colocados após liasse .
    2. Se não houver esse objeto, grep pode obter literal *.sas como um caminho a ser inspecionado (depende; investigue, por exemplo, shopt -s nullglob , shopt -s failglob em bash ) e ative o aviso.
  2. De qualquer forma, grep obtém ./ e processa-a recursivamente em uma pesquisa por liasse nos arquivos. Isso processa todos os arquivos em ./ : programs, tables, whatever.

É por isso que você pode obter um nome de tabela no seu resultado.

Meu comando find . -type f -name '*.sas' -exec grep -li liasse {} + runs grep apenas para arquivos que correspondem a *.sas pattern. Coisas importantes:

  • -type f escolhe somente arquivos. Dessa forma eu evito que nomes de diretórios correspondendo *.sas (se houver) sejam passados para grep ( grep sem -r deve rejeitá-los de qualquer maneira, mas seria menos elegante).
  • Citando o padrão impede o shell de globbing; find obtém literal *.sas como um argumento para o operando -name ; sabe interpretar padrões como este.
  • A sintaxe find … -exec … {} + substitui vários objetos no lugar de {} . Desta forma, menos (talvez apenas um) grep processos são criados, em comparação com find … -exec … {} \; .
por 11.01.2018 / 10:43
1

Você pode usar o comando find para localizar recursivamente todos os arquivos pelo nome e, em seguida, executar grep em cada arquivo. A solução mais simples é a opção -exec de find:

find . -name '*.sas' -exec grep -li liasse {} \;

Como alternativa, você pode combinar find com xargs :

find . -name '*.sas' -print0 | xargs -0 grep -li liasse

Isso tem um desempenho um pouco melhor, porque executa grep para um grande lote de arquivos, não para cada arquivo.

Usando a opção -P de xargs , você pode até executar múltiplas invocações grep em paralelo.

    
por 11.01.2018 / 09:46
-1

Isso pode ser conseguido com

find . -type f -name "*.sas" -print0 | "xargs" -0 -e grep -liH -e liasse

Se você não tiver a implementação xargs com a opção -0 , que é sobre a comunicação de um conjunto de caminhos entre find e xargs , tente

 find . -type f -name "*.sas" -print | "xargs" -e grep -liH -e liasse
    
por 11.01.2018 / 09:40

Tags