ティーでgrepする方法?

ティーでgrepする方法?

コマンド出力に「rerun」(その後再実行)が含まれているかどうかを確認したいのですが、出力全体も表示したいと思います。次のいずれかを使用できることを知っています。

command | tee >(grep rerun)
command | grep rerun

最初は、期待どおりに出力全体を印刷しますが、常にゼロを返すため、条件として使用できません。 2 番目は rerun を含む行のみを印刷しますが、一致するものがない場合は 1 を返します。

私の使用例:

while pdflatex paper.tex | grep -E "rerun LaTeX|run Biber"; do
    biber paper
done

ここで提供された回答grepは常に0を返すので役に立ちません。

答え1

ただ使用

command | tee outfile | grep rerun

または

while pdflatex paper.tex | tee outfile | grep -E "rerun LaTeX|run Biber"; do

grepコマンドのステータスを確認し、後で「output」ファイルを表示できます。

答え2

ファイルを表示してそのファイルをgrepできます。その後、終了コードをgrepできます(0は一致を意味します)。

RERUN=1
while [[ $RERUN == 1 ]] ; do
  biber paper
  ! pdflatex paper.tex | tee output.txt && grep -E -q "rerun LaTeX|run Biber" output.txt
  RERUN=$?
done

行4では、!grepが一致を見つけた場合は0を返し、一致がない場合は1を返すので、grepプロセスの終了コードを逆に置き換えます。grep のマニュアルページ:

終了ステータス

   Normally the exit status is 0 if a line is selected, 1 if no lines were
   selected, and 2 if an error occurred.  However, if the -q or --quiet or
   --silent is used and a line is selected, the exit status is 0  even  if
   an error occurred.

行5では、最後の終了コード($?)をループ条件に使用されるRERUN変数に入れます。

また、-qstdoutに書き込まないようにgrepにオプションを追加しました。

答え3

stdout即時の表示に固執する場合は、grepプロセスオーバーライドの出力をファイルにリダイレクトして出力の重複行を防ぐ必要があるため、次のことを行う必要がありますcommand | tee >(grep rerun >/tmp/my.log)

[[ -s /tmp/my.log ]]ファイルが作成されたら、それを再実行条件として使用するだけです。

関連情報