Awk
awk 無法處理 sed 的管道輸出
我有一個大致如下所示的日誌文件:
Sep 23 10:28:26 node kernel: em0: device is going DOWN Sep 23 10:28:26 node kernel: em0: device is going UP Sep 23 10:29:14 node cdsmon: /tmp/instance0 ; core dumped Sep 23 10:29:14 node cdsmon: /tmp/instance0 ; core dumped Sep 23 10:28:26 node kernel: em0: device is going DOWN Sep 23 10:29:14 node cdsmon: /tmp/instance1 ; core dumped Sep 23 10:28:26 node kernel: em0: device is going UP Sep 23 10:29:14 node cdsmon: /tmp/instance2 ; core dumped
我想用 檢測線條,
cdsmon
然後將線條分割;
(以獲取/tmp/instance0
和 之類的事件core dumped
)。為此,我用作
sed
:sed -u -n -e "s/^.*cdsmon: //p" /tmp/dev.log
輸出為:
/tmp/instance0 ; core dumped /tmp/instance0 ; core dumped /tmp/instance1 ; core dumped /tmp/instance2 ; core dumped
但是在將這個輸出傳送到
awk
如下所示時,它會給出與上面相同的輸出:sed -u -n -e "s/^.*cdsmon: //p" /tmp/dev.log | awk -F ";" "{print $1}"
儘管
-u
從sed
.誰能指出我是否遺漏了什麼?我正在使用帶有正常 awk/sed 的 FreeBSD 機器,不幸的是無法安裝任何新軟體包。
的行為的原因
awk
是您已將程序括在雙引號中,這使字元串對 shell 的變數擴展開放。這意味著您執行程序的 shell 將首先展開$1
,並且由於這可能是未定義的,它會展開為空字元串。所以,你的程序相當於
awk -F ";" "{print}"
這就是列印整行的原因。這是您應該始終將
awk
(andsed
) 程序包含在單引號中的原因之一。請注意,在大多數情況下,您不需要將輸出從管道輸入,
sed
反之亦然awk
。在您的範例中,如果您想獲取“事件標籤”之後的第一個欄位,您可以執行以下操作:sed -E -n 's/^.*cdsmon: ([^;]*).*$/\1/p' /tmp/dev.log
這將圍繞字元串定義一個擷取組
cdsmon:
,直到 first;
,並將整行替換為該擷取組的內容。如果要列印由 記錄的事件的摘要
cdsmon
,可以將上述sed
方法擴展為:sed -E -n 's/^.*cdsmon: ([^;]*) ; (.*)$/\1 : \2/p' dev.log
或者,這是另一種
awk
-only 方法:awk -F'(cdsmon: | ; )' 'NF==3{printf "%s : %s\n",$2,$3}' dev.log
對於您的範例,兩者都將列印
/tmp/instance0 : core dumped /tmp/instance0 : core dumped /tmp/instance1 : core dumped /tmp/instance2 : core dumped
但請注意,該
awk
方法可能會遇到極端情況。它採用模式cdsmon:
和;
作為欄位分隔符。當有三個欄位時(在您的範例中,它只能發生在cdsmon:
條目中),它會列印第二個和第三個欄位,對應於實例名稱之後cdsmon:
和原因之後;
。