2011-08-23 11 views
532

grepを連続ストリームで使用できますか?連続したストリームを 'grep'する方法はありますか?

私が意味するのは、tail -f <file>コマンドですが、出力にgrepを付けて、興味のある行だけを残しています。

私はtail -f <file> | grep patternを試しましたが、grepは一度だけ実行することができます。tailは決して終了しません。

+29

'tail -f file | grep pattern'はうまくいくはずです。 –

+8

ファイルを生成するプログラムが出力をフラッシュしていない可能性があります。 –

+0

'tail -f file'が動作する(私はリアルタイムで新しい出力を見る) –

答えて

989

grepの回線バッファリングモードをオンにします。

tail -f file | grep --line-buffered my_pattern 
+26

これは受け入れられる答えです。 – Patryk

+2

これが実行されている間に、回転されたログファイルを私が追跡するとどうなりますか? logrotateでファイルをローテートできますか? –

+3

@MichaelNiemandあなたはtail -F file | grep -line-buffered my_pattern – jcfrei

97

私はいつもtail -f <file> | grep <pattern>を使用しています。

grepが終了するまで待つことになります(私はUbuntuを使用しています)。

+3

これはかなりの間続くことができるので、辛抱強くしないでください。 – glglgl

+0

どのくらいの期間かかりますか? –

+0

@Matthieu:主にあなたがgrepの対象と、あなたのOS上のバッファの大きさに依存します。 grepが数時間ごとに短い文字列と一致する場合、最初のフラッシュの前の日になります。 – tripleee

0

はい、実際はうまくいきます。 GrepとほとんどのUnixコマンドは一度に1行ずつストリームで動作します。尾から出てくる各行は分析され、一致する場合に渡されます。

+1

これは実際には正しくありません。 'grep'がパイプチェーンの最後のコマンドであれば、あなたが説明するように動作します。しかし、途中であれば、一度に8k出力をバッファリングします。 –

47

あなたの問題は、grepがいくつかの出力バッファリングを使用していると思います。試してください。

tail -f file | stdbuf -o0 grep my_pattern 

grepの出力バッファリングモードをバッファなしに設定します。

+5

これは、 'grep'以外の多くのコマンドにも使用できるという利点があります。 –

+4

しかし、それ以上のプレイをした後で発見したように、ttyに接続したときに出力をフラッシュするコマンドもあります。そのため、 'unbuffer'(debianの' expect-dev'パッケージ)は* king *です。だから私はstdbuf上のバッファーを使用します。 –

+4

@Peter V.Mørchはい、そうです。stdbufが実行できない場所でバッファリングされていないことがあります。しかし、私はあなたの問題を理解するのではなく、あなたの問題を常に修正する「魔法の」プログラムを見つけることを試みていると思います。仮想ttyを作成することは無関係な作業です。 Stdbufは私たちが望むものを正確に(標準出力バッファに値を与えるように設定します)、unbufferは(stdbufとunbufferと対話型の 'top'を比較して)望ましくないかもしれない隠されたものをたくさんします。そして、実際には「魔法の」解決策はありません。例えば、unbufferは時には失敗します。たとえば、awkは異なるバッファ実装を使用します(stdbufも失敗します)。 – XzKto

-3

grepの代わりにawk(別の偉大なbashユーティリティ)を使用してください。ここでは、バッファリングオプションはありません。それはあなたのデータを尾から連続的にストリーミングします。

これは、あなたがこれはあなたがtail -f /var/log/some.log |grep fooすることができますし、それがうまく動作しますが、あなたは多くの場合のawk

tail -f <file> | awk '/pattern/{print $0}' 
+5

これは正しくありません。他の多くの標準的なUnixツールと同様に、すぐに使えるように、ラインバッファリングを実行します。 (さらに、 '{print $ 0}'は冗長です。条件が成立したときに印刷がデフォルト動作になるので)。 – tripleee

4

を使用する方法であるgrepを

tail -f <file> | grep pattern 

を使用する方法です。

あなたが実行してログファイルに複数のgrepするを使用する必要があり、あなたは何も出力を得るていないことが判明した場合、あなたはそのように、あなたの真ん中のgrep(複数可)に--line-bufferedスイッチを固執する必要があります。

tail -f /var/log/some.log | grep --line-buffered foo | grep bar 
1

あなたは

(ファイルが回転した場合-fが正しく動作しません)通常、私は

tail -F <fileName> | grep --line-buffered <pattern> -A 3 -B 5 

-Fは、ファイルの回転の場合に優れているを使用しています。..拡張として、この答えを考えることができます3210

-Aと-Bは、パターンの直前と直後に行を取得するのに便利です。これらのブロックは、あなたが特定のを見つけ、一度終了するtailコマンドを望んでいた場合

+1

'grep -C 3 'は、Nが同じ場合は-A と-B を置き換えます。 –

-1

はその後、適切なコマンドになり(ストリームエディタ)

tail -n0 -f <file> | sed -n '/search string/p'

とををsedの破線のセパレータ間に登場します文字列:明らか

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

bashism:$ BASH PIDはtailコマンドのプロセスIDです。 sedコマンドはパイプの末尾の次にあるので、sedのプロセスIDは$ BASHPID + 1になります。

+1

システム($ BASHPID + 1)で開始された次のプロセスがあなたのものになるという仮定は多くの状況では偽です。これはおそらくOPが尋ねようとしていたバッファリングの問題を解決するものではありません。特に、ここで 'grep 'に' sed'を推奨するのは単なる疑わしい(疑わしい)好みのようです。 (あなたが配信しようとしているポイントであれば 'grep -m 1'で' p; q'の動作を得ることができます。) – tripleee

2

あなたは全体ファイル(だけでなく、尾)でマッチを見つけたい、とあなたはそれが座っていると、新しいマッチを待つしたい場合は、これがうまく動作:

tail -c +0 -f <file> | grep --line-buffered <pattern> 

-c +0フラグファイルの先頭(+)から出力が0バイト(-c)になるはずです。

関連する問題