2017-12-19 6 views
1

テキストファイルを反復処理する必要がありますが、最初の行で停止するwhileループがありますが、理由を特定できません。私のコードは以下の通りです。whileループは、bashのファイルの最初の行でのみ動作します

while read hadoop_accounts; do 
     if ! grep "no lock no remove"; then 
       echo "${hadoop_accounts%%:*}" 
       echo "${hadoop_accounts%%:*}" >> missing_no_lock_no_remove.txt 
     fi 
done < hadoop_accounts.txt 

答えて

3

grepを明示的リダイレクトまたは読み込みファイルなしで実行すると、stdinが読み込まれます。 すべて of stdin。あなたのwhile readループと同じstdinが読んでいます。

したがって、すべての標準入力がgrepで消費された場合、次のreadコマンドで消費することはありません。

while IFS= read -r hadoop_accounts; do 
     if ! [[ $hadoop_accounts = *"no lock no remove"* ]]; then 
       echo "${hadoop_accounts%%:*}" 
       echo "${hadoop_accounts%%:*}" >&3 
     fi 
done < hadoop_accounts.txt 3>> missing_no_lock_no_remove.txt 


簡単なアプローチ(およびパフォーマンスのためのより良い)は、シェル内部の部分文字列のチェックを行い、そして全てで処理ラインあたりgrepの新しいコピーを起動する気にしないことです

出力ファイルを一度しか開いていないので、一度に1行書きたいとは限りません。あなたが本当にはしかし、1行のみの入力が毎回で何度も繰り返しgrepを呼び出したい場合は


、あなたははそれを行うことができます。

while IFS= read -r hadoop_accounts; do 
     if ! grep "no lock no remove" <<<"$hadoop_accounts"; then 
       echo "${hadoop_accounts%%:*}" 
       echo "${hadoop_accounts%%:*}" >&3 
     fi 
done < hadoop_accounts.txt 3>> missing_no_lock_no_remove.txt 

あるいは、上記のいずれよりも優れていても、grepを入力ファイル全体に1回だけ実行し、ループ内で出力を読み取ることができます。

while IFS= read -r hadoop_accounts; do 
    echo "${hadoop_accounts%%:*}" 
    echo "${hadoop_accounts%%:*}" >&3 
done < <(grep -v 'no lock no remove' <hadoop_accounts.txt) 3>>missing_flags.txt 
+0

奇妙なことは、私が今使っているものに似た構文を間違いなく使っていて、うまくいきました。それから、私はgrep検索条件を変更してそれを破ったが、私が前にしたことを忘れてしまった。 迅速かつ詳細な対応とパフォーマンスの向上に感謝します。 編集:ああ、私は<<< "hadoop_accounts"が不足していましたが、私はあなたがもっと多くを提案した他の方法が好きです。私はむしろシェルスクリプトの初心者ですので、もう一度非常に感謝しています! – Josh

関連する問題