Redirecionando comandos grep em loop para separar arquivos

2

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

Eu fiz uma tentativa (usando esta pergunta como um guia ) e veio 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 eu 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 esse script? Ou estou me aproximando disso errado?

    
por PaleSaint 17.02.2016 / 18:55

1 resposta

2

Existem alguns problemas aqui:

  1. O loop while 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, pendurado, aguardando a entrada. Você pode testar isso executando seu script e, em seguida, digitando qualquer coisa e pressionando enter (aqui, digitei foo ):

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

    Você pode melhorar isso adicionando uma solicitação ao seu read :

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

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

  2. O || [[ -n "$line" ]] (que significa "OU a variável $ linha não está vazia") nunca é executado. Como read trava, o "OR" nunca é alcançado. Eu não entendo o que você queria fazer de qualquer maneira. Se você quiser pesquisar por $line se $line estiver definido e usar read , se 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 $line não estiver definido, você ainda precisará inseri-lo manualmente. Uma abordagem mais limpa seria alimentar um arquivo no loop while :

    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
    
por 17.02.2016 / 19:36

Tags