このコードを実行するとき:
while true; do printf "Match Unmatch\n"; sleep 1s; done | grep -o "Match"
ターミナルでgrep
次の単語を見つけMatch
ます。
Match
Match
Match
...
しかし、次のコードを実行すると:
while true; do printf "Match Unmatch"; sleep 1s; done | grep -o "Match"
それからgrep
何も見つからないようです。少なくとも何も印刷されません。 grepが決して来ない改行文字を待っていますか? grep、sed、または同様のツールが改行なしでストリームから一致をキャプチャするようにする方法はありますか?
答え1
Grepは基本的に与えられたパターンに一致する行を探します。パターンによっては、行全体を見ることなく行が一致するかどうかを判断することは不可能かもしれません。ではgrep Match
可能ですが、grep 'Match$'
では不可能です。 grepを使用すると、grep -o Match
grepはMatch
すぐに印刷できますが、grep -E -o '(Match)+'
grepを使用するとそれに従うMatchMa
かどうかはわかりません。tch
Grepは、行全体が表示される前にいくつかの出力が書き込まれる可能性がある特別なケースを実装しません。 (現実ではないと思います。どのこれは特別なケースですが、わかりません。 GNU grepには、モードによって若干異なる動作をするいくつかのモードがあります。 ) 一致を試みる前に行全体を読みます。
一致するテキストにまったく表示されず、一致する項目の間に常に(または少なくとも頻繁に)表示される文字がある場合は、その文字を改行文字に変換します。 (またはヌルバイトに行ってそれを使用してくださいgrep -z
。)
while true; do printf "Match Unmatch"; sleep 1s; done | stdbuf -o0 tr ' ' '\n' | grep -o "Match"
出力バッファリングをstdbuf -o0
防ぐために、この機能を慎重に使用してください。tr
grepの出力をパイプしたり(buffered)使用する場合でも、grepが必要ですgrep --line-buffered
。--line-buffered
出力grepの場合、grepが入力を読み取る方法に影響を与えず、grepが端末に印刷されるときにデフォルトでオンになっています。 )