ループされた grep コマンドを別のファイルにリダイレクトする

ループされた grep コマンドを別のファイルにリダイレクトする

grep を使用して、ファイルにリストされているパターンを使用してディレクトリを再帰的に検索し、各結果を後で参照できるように独自のファイルに保存したいと思います。

私は(この質問ガイドとして、次のような結論に至りました。

#!/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."

しかし、実行すると、CTRL-C を押すまでコンソールがハングします。

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

このスクリプトの問題点はどこにあるのでしょうか? それとも、私が間違ったアプローチをしているのでしょうか?

答え1

ここでいくつか問題があります:

  1. ループwhileは入力を読み込んでいません。正しい形式は

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

    または

    some other command | while read ...
    

    したがって、ループは入力を待ってハングします。スクリプトを実行し、何かを入力して Enter キーを押すと、これをテストできます (ここでは と入力しましたfoo)。

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

    次のプロンプトを追加することで、これを改善できますread:

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

    Ctrlただし、 +で停止するまでは実行され続けますC

  2. || [[ -n "$line" ]](「OR 変数 $line が空でない」という意味) は実行されません。 がハングするため、 「OR」に到達することはありません。 とにかく、何をしたかったのかわかりません。が定義されているかreadどうかを検索し、定義されていない場合は を使用する場合は、次のようなものが必要になります。$line$lineread

    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
    

    ここで、$lineが定義されていない場合は、手動で入力する必要があります。よりクリーンなアプローチは、ループにファイルを入力することです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
    

関連情報