Redirecionando comandos grep em loop para arquivos separados

Redirecionando comandos grep em loop para arquivos separados

Eu gostaria de usar o grep para pesquisar recursivamente em um diretório, usando padrões listados em um arquivo e, em seguida, armazenar cada resultado em seu próprio arquivo para referência posterior.

Eu fiz uma tentativa (usandoessa questãocomo guia) e surgiu com:

#!/bin/bash

mkdir -p grep_results   # For storing results

echo "Performing grep searches.."
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "Seaching for $line.."
    grep -r "$line" --exclude-dir=grep_results . > ./grep_results/"$line"_infile.txt
done

echo "Done."

No entanto, quando o executo, o console trava até eu pressionar CTRL-C:

$ bash grep_search.sh search_terms.txt
Performing grep searches..

Onde está o problema com este script? Ou estou abordando isso errado?

Responder1

Existem alguns problemas aqui:

  1. O whileloop não está lendo nenhuma entrada. O formato correto é

    while read line; do ... ; done < input file
    

    Ou

    some other command | while read ...
    

    Seu loop está, portanto, suspenso, aguardando entrada. Você pode testar isso executando seu script e digitando qualquer coisa e pressionando Enter (aqui eu digitei foo):

    $ foo.sh 
    Performing grep searches..
    foo
    Searching for foo..
    

    Você pode melhorar isso adicionando um prompt ao seu read:

    while IFS='' read -p "Enter a search pattern: " -r line ...
    

    Isso ainda funcionará até que você pare com Ctrl+ C.

  2. O || [[ -n "$line" ]](que significa "OU a variável $line não está vazia") nunca é executado. Desde que readtrava, o "OR" nunca é alcançado. Eu não entendo o que você queria fazer de qualquer maneira. Se você quiser pesquisar $linese $lineestá definido e usar readse não estiver, você precisará de algo como:

    if [[ -n "$line" ]]; then
         grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt
    else
        while IFS='' read -p "Enter a search pattern: " -r line || [[ -n "$line" ]]; do
          grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt
        done
    fi
    

    Aqui, se $linenão estiver definido, você ainda precisará inseri-lo manualmente. Uma abordagem mais limpa seria alimentar um arquivo no whileloop:

    while IFS='' read -r line || [[ -n "$line" ]]; do
      grep -r "$line" --exclude-dir=grep_results > ./grep_results/"$line"_infile.txt
    done < list_of_patterns.txt
    

informação relacionada