Bashパイプラインのノードはどのように入力ストリームを見ることができますが、使用しないのですか?

Bashパイプラインのノードはどのように入力ストリームを見ることができますが、使用しないのですか?

Bashパイプラインのノードはどのように入力ストリームを使用せずに表示することができますか?

たとえば、何も印刷せずに「印刷」を印刷するように、次のスクリプトをどのように変更しますか?具体grep --quiet print的には、閲覧だけで入力を消費しないように変更または交換するにはどうすればよいですか?

printf "%s\n" a b print c |
  if grep --quiet print
  then
    grep print | cat
  fi

出力:


希望の出力:

print

peekgrep理想的には似ていますが、入力を使用しないプログラムを探しています。peek print入力に「print」が含まれている場合はエラーコード0が返され、それ以外の場合は0以外のエラーコードが返されます。

peek私の例で動作する方法は次のとおりです。

printf "%s\n" a b print c |
  if peek print
  then
    grep print | cat
  fi

出力:

print

単に結果をフィルタリングするのではなく、これを行う理由は、grep printエラーが発生する可能性がある空の検索結果を処理しないためです。

答え1

私が考えることができる簡単な方法の1つは、出力に一時ストアを使用することです。これは、以下のようにコードを最小限に変更することで実現できます。

atmp=$(mktemp "/tmp/XXXXXX")

printf "%s\n" a b print c | tee $atmp | 
  if grep --quiet print
  then
    grep print $atmp 
  fi  
rm $atmp #cleanup

これは小規模な出力配置に適している可能性があります。

答え2

@Tagwintに似た別のアプローチ回答結果をシェル変数に保存grep printし、検索結果がある場合にのみその変数の内容を印刷します。

printf "%s\n" a print b print c |
 if result=$(grep print)
 then
   echo "$result";
 fi

出力:

print
print

これは、検索結果が大きすぎない場合に許可されます。

答え3

fionreadまた、以下を使用してこの特定の例の問題を解決しました。@モスビー彼の実装回答到着パイプが空であることを確認し、空である場合は、データに対してコマンドを実行するにはどうすればよいですか?

printf "%s\n" a b print c | grep print | ./fionread echo found

出力:

found
printf "%s\n" a b c | grep print | ./fionread echo found

出力:


これはFreeBSD 11.3で簡単にコンパイルされますgccfionread.c

$ gcc -o fionread fionread.c
$ echo test | grep test | ./fionread echo found
found
$ echo | grep test | ./fionread echo found
$

答え4

標準の Unix ユーティリティや Bash スクリプトではありませんが、以下を使用してこの特定の例の問題を解決することにしました。ifne~からその他のユーティリティ:

printf "%s\n" a b print c | grep print | ifne echo found

出力:

found
printf "%s\n" a b c | grep print | ifne echo found

出力:


@ニックワースlfne彼の記事で言及されている回答到着パイプが空であることを確認し、空である場合は、データに対してコマンドを実行するにはどうすればよいですか?

ありがとう@モスビー~のため引用するこの既存の質問に答えます。

関連情報