awk を使用して grep 出力形式を指定します。シンプルケースとバックグラウンドケース

awk を使用して grep 出力形式を指定します。シンプルケースとバックグラウンドケース

私はこの問題を解決しようとしています。私は次の行を持っています:

mplayer *.* 2>/dev/null | grep Playing

開始されたばかりで、mplayer一致する行だけが画面に印刷されました。これは、現在再生中のメディアを変更するたびに機能します。Playing filename

grepの出力を「フォーマット化」することが可能かどうか疑問に思います。たとえば、出力が次のような場合:

Playing Pink_Floyd-Wish_You_Were_Here.mp3  # I get this at the beginning
Playing Pearl_Jam-Once.mp3                 # I get this after I change media inside mplayer

それから私は次のようになります:

Mplayer: Playing Pink_Floyd-Wish_You_Were_Here.mp3
Mplayer: Playing Pearl_Jam-Once.mp3

そのためにawkを使用することにしました。

mplayer *.* 2>/dev/null | grep Playing | awk '{print "Mplayer: "$1}'

しかし、この場合は何も起こりません。

私の質問はmplayerの問題を解決するのではなく、bashのパイプのより深い理解を得ることです。

たとえば、次のような場合:

echo a_song.mp3 | awk '{print "Mplayer: "$1}'

欲しいものを手に入れる

Mplayer: a_song.mp3

最初のコマンドが機能しないのはなぜですか?

バックグラウンドでこれらのプロセスを複数実行するにはどうすればよいですか?

答え1

たくさんgrep標準出力が端末の場合、実装はラインバッファリングを使用します。標準出力が端末の場合は通常対話型セッションなので、できるだけ早くデータを取得しようとします。したがって、grep改行文字が表示されるとすぐにデータが標準出力に書き込まれます。

標準出力が端末でない場合(通常は非対話型セッションを意味する)、grepブロックバッファが使用されます。これはgrep、改行文字が表示されたときに標準出力がすぐに書き込まれないことを意味します。grep標準出力に書き込む前に、大量のデータ(Linuxでは4096バイト)を収集します。

いくつかのgrepバージョン、例:GNU grepまたはBSD grep持つ--ラインバッファリングオプション。grep改行文字が表示されたら、常に標準出力に書き込みます。したがって、あなたの例は次のとおりです。

mplayer *.* 2>/dev/null | grep --line-buffered Playing | awk '{print "Mplayer: "$1}'

grepあなたのバージョンがそうでない場合は、--line-buffer以下を使用してすべての操作を実行できますawk

mplayer *.* 2>/dev/null | awk '/Playing/{print "Mplayer: "$1}'

GNU coreutilsにはツールがあります標準バッファコマンドを修正するためのバッファです。以下を使用して、いつでも標準出力にラインバッファを強制的に適用できます。

stdbuf -oL command

しかもバッファリング解除出力バッファリングを無効にするコマンドのみが適用されます。

追加読書

関連情報