Suponhamos que eu queira encontrar todos os .txt arquivos e pesquisar alguma string. Eu faria:

find ./ -type f -name "*.txt" -exec egrep -iH "something" "{}" \; 

E se eu quiser fazer uma filtragem mais complexa, como esta:

egrep something file.txt | egrep somethingelse | egrep other 

Por dentro de find -exec? (ou semelhante)

Lembre-se de que estou procurando uma solução que possa digitar facilmente quando precisar. Eu sei que isso poderia ser feito com algumas linhas usando um script de shell, mas não é isso que estou procurando.

Resposta

Se você deve fazer isso de dentro de find, você precisa chamar um shell:

find ./ -type f -name "*.txt" -exec sh -c "grep -EiH something "$1" | grep -E somethingelse | grep -E other" sh {} \; 

Outras alternativas incluem o uso de xargs em vez:

find ./ -type f -name "*.txt" | xargs -I{} grep -EiH something {} | grep -EiH somethingelse | grep -EiH other 

Ou , muito mais seguro para nomes de arquivo arbitrários (assumindo que seu find suporte -print0):

find ./ -type f -name "*.txt" -print0 | xargs -0 grep -EiH something {} | grep -Ei somethingelse | grep -Ei other 

Ou, em vez disso, você pode usar apenas um loop de shell:

find ./ -type f -name "*.txt" -print0 | while IFS= read -d "" file; do grep -Ei something "$file" | grep -Ei somethingelse | grep -Ei other done 

Comentários

  • O primeiro é exatamente o que eu procurava. Extremamente simples e pequeno o suficiente para digitar dependendo das minhas necessidades. Obrigado.
  • … e xargs também poderiam ser usados como xargs -I {} sh -c '...' sh {}, se alguém quisesse (faz é possível executar trabalhos paralelos com -P se alguém quiser).

Resposta

Editar: esta resposta é não preferida , mas é deixada aqui para comparação e ilustração de armadilhas potencialmente perigosas no script bash.


Você pode colocar bash (ou outro shell) como seu comando -exec:

 find -type -f -name "*.txt" -exec bash -c "egrep -iH something "{}" | egrep somethingelse | egrep other" \;  

Uma das desvantagens de fazer dessa forma é que cria mais potencial para problemas de cotação aninhados conforme seus comandos se tornam mais complexos. Se quiser evitar isso, você pode dividi-lo em um for -loop:

 for i in $(find -type -f -name "*.txt"); do if egrep -iH something "$i" | egrep somethingelse | egrep other; then echo "Found something: $i" fi done  

Comentários

  • O primeiro é exatamente o que eu estava procurando. Extremamente simples e pequeno o suficiente para digitar dependendo das minhas necessidades. Obrigado.
  • Esse for loop é uma ideia muito ruim. Também conhecido como bash pitfall # 1 .
  • Este "{}" em seu primeiro comando pode até levar à injeção de código. Imagine que você tenha obtido arquivos comigo e ' um arquivo chamado literalmente " & rm -rf ~ & : ".txt. Felizmente para você -type -f é inválido, acabou de salvar seu diretório pessoal. Corrija o erro de digitação e tente novamente. 🙂 terdon fez certo: find … -exec sh -c '… "$1" …' foo {} \;.
  • Obrigado pela informação! Sim, o -type -f é um erro de digitação que cometi constantemente ao usar find e não ' não percebo na minha resposta. Opa. terdon ' a resposta é melhor, mas ' deixarei isso para fins comparativos.
  • @terdon: tx para consultar a página mywiki.wooledge.org. É ' bom ter um monte de GPs perfeitamente resumidos em um só lugar.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *