パイプラインで tee 部分が一致をファイルに誘導できるように、`tee` と `grep` を組み合わせたコマンドはありますか?

パイプラインで tee 部分が一致をファイルに誘導できるように、`tee` と `grep` を組み合わせたコマンドはありますか?

ファイルから複数のピースをプルするか、少なくともピースが発生した場合にログ ファイルでピースを監視したいのですが、複数のtail | grepセッションをセットアップしたくありません。代わりに、各 grep の出力を tail したいだけです。

でこれを行うこともできると思いますawkが、おそらくこのアイデアに近いものがすでに存在しているでしょう。

たとえば、コマンドは次のようになります。

tail -f /var/log/syslog | teegrep cron1 -f CRON | teegrep cloud-init2 -f CLOUD-INIT

出力は CRON ファイルと CLOUD-INIT ファイルになりますが、最後にはすべてが標準出力に送られます。「cron1」と「cloud-init2」の行に一致するものだけがそれぞれのファイルに出力されます。

おそらく、これはすでにコマンドの一部で、私が知らなかっただけでしょう。あるいは、同じことを実行する bash/zsh のトリックかもしれません。いずれにしても、パイプラインで tee 部分が一致をファイルに送ることができるように、 と をtee組み合わせるコマンドはありますか?grep

答え1

プロセス置換機能を備えたシェルを想定すると、次のようになります>(...)

tail -f /var/log/syslog | 
tee >(grep cron1 >CRON) | 
tee >(grep cloud-init2 >CLOUD-INIT)

これにより、パイプラインのtail最初の にデータが生成されます。 はデータを複製し、1 つのコピーを次の に送り、もう 1 つをプロセス置換に送ります。そのプロセス置換はから到着するデータに対して実行され、結果はファイル に送られます。teeteeteegrepteeCRON

パイプラインの最後のステージも同様に動作します。


プロセス置換が使用できないシェルでは、/bin/shまたはawksed使用できます。

awk

tail -f /var/log/syslog | 
awk '{ print }
     /cron1/       { print >"CRON" }
     /cloud-print/ { print >"CLOUD-INIT" }'

(コマンドは常にファイルにデータを追加するsedため、出力ファイルが存在しないことを確認する必要があることに注意してください)wsed

rm -f CLOUD CLOUD-INIT

tail -f /var/log/syslog | 
sed -e '/cloud/w CLOUD' \
    -e '/cloud-print/w CLOUD-INIT'

関連情報