Awk
使用 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
為什麼第一個命令不起作用?
如果我想在後台執行多個這樣的程序,我該怎麼辦?
當標準輸出為終端時,許多grep實現將使用行緩衝。當標準輸出是終端時,通常是一個互動式會話,您希望盡快獲取數據。因此
grep
,一旦看到換行符,就會將數據寫入標準輸出。當標準輸出不是終端時(通常意味著非互動式會話),
grep
將使用塊緩衝區代替。這意味著grep
在看到換行符時不會立即寫入標準輸出。grep
在寫入標準輸出之前收集數據量(Linux 中為 4096 字節)。某些
grep
版本,例如GNU grep或BSD grep具有–line-buffered選項。當看到換行符時,它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 。您始終可以使用以下命令強制標準輸出中的行緩衝區:
stdbuf -oL command
還有unbuffer命令僅禁用輸出緩衝。
進一步閱讀