web-dev-qa-db-ja.com

awkへのtail -fのパイピング

私はtail -fをawkにパイプしてリアルタイムでログファイルを監視しようとしていますが、例によれば問題はないはずですが、動作させることができません。

ここに私が実行しているコマンドがあります

tail -f logfile.log | awk -F" " '{print $1, $2, $7, $8}'

しかし、nano add a lineを使用してファイルを編集すると、リアルタイムで印刷されません。awkコマンドを直接実行すると、新しい行が結果に表示されます。

8
gimpycpu

効率のためにパイプはバッファリングされるため、リアルタイムでは表示されません。 tail -fは、出力がawkに渡される前に、バッファ(通常は4 kB)をいっぱいにする必要があります。

修正は、expectパッケージの一部であるunbufferコマンドを使用することです。

unbuffer tail -f logfile.log | awk -F" " '{print $1, $2, $7, $8}'

これはtailをだまして、インタラクティブな端末に書き込んでいると思い込ませます。その結果、バッファリングされません。

詳細については、 https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe を参照してください

または、GNU coreutils 7.5以上を使用している場合は、stdbufコマンドで出力バッファリングを無効にすることができます。

stdbuf -o0 tail -f logfile.log | awk -F" " '{print $1, $2, $7, $8}'
11
John1024

@ John1024の答え は、stdbuf -o0接頭辞が間違っているため、正しくありません。これは、tail -fコマンドではなく、awkコマンドのプレフィックスとして属しているため、正しいコマンドは次のとおりです。

tail -f logfile.log | stdbuf -o0 awk -F" " '{print $1, $2, $7, $8}'

また、awkのすべてのバージョンがその特定の構成で機能するわけではないことにも注意してください。 IOW、その特定のコマンド文字列を記述どおりに機能させる必要がある場合は、機能するバージョンが見つかるまで、さまざまなawk/gawk/mawkバージョンを試してください。

6
kenneth558

以下の例に示すように、whileループを追加することで、バッファリングを解除できます。これを実行中のログファイルでテストしましたが、うまくいきました。

tail -f input.log | while read a; do echo "$a" | awk -F" " '{print $1, $2, $7, $8}' >> output.log; done
2
SonicAddiction

Stdbufもunbufferも機能しないようです(Ubuntu 18.04)。ただし、名前付きパイプを使用すると機能します。以下を含むシェルスクリプトを作成しました。

mkfifo /tmp/pipe
awk -F" " '{print $1, $2, $7, $8}' < /tmp/pipe &
tail -f input.log > /tmp/pipe
0
Phil Mercurio