web-dev-qa-db-ja.com

ログファイルの末尾を表示しますが、特定の行のみを表示します

ログファイルの末尾に-fフラグを付けています。次に、これをgrepにパイプして、「X」を含む行のみを検索します。それは完全にうまく機能しています。次に、これを別のgrepに再度パイプします。これにより、「Y」を含むすべての行が削除されます。 2番目のパイプを追加すると、ファイルの更新が停止し、データが到着していないように見えます。

これは機能するコマンドです:tail -f my_file.log | grep "X"

これはしないコマンドです:tail -f my_file.log | grep "X" | grep -v "Y"

コマンドが機能するようにこれをどのように構成する必要がありますか?

25
Ori Horev

grepの出力はバッファリングされるので、grep--line-bufferedオプションを使用して行バッファリングを有効にします。

tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'

grepにオプションがない場合は、代わりにstdbufを使用できます。

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'
34
heemayl

私は通常、これらの種類の論理チェックに役立つawkを見つけます。

tail -f /path/to/log | awk '/X/ && !/Y/'
#                           ^^^    ^^^^
#                   this I want    but not this

2つのタブを使用してテストしました。1つはseq 20 >> myfileを書き続け、もう1つはtail -f myfile | awk '/3/ && !/13/'を書きます。

18
fedorqui

別のアプローチは、2回ではなく1回のgrep呼び出しを使用することで、バッファリングの問題を回避することです。 0個以上のY以外の文字で構成される行に一致する正規表現を使用し、次にX、次に行の終わりまで0個以上の非Yを再度使用します。

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
15
terdon