2015-06-03 56 views
0

我試圖讓我的程序通過日誌文件進行解析,試圖找到單詞「user」並將其打印出來,或打印出「N/A」if它沒有找到它。這第一行代碼是我原來的例子之前,我試圖在else語句來寫:如果表達式不在記錄中打印

awk '{for(i=1;i<=NF;i++){if($i~/^user/){print $i}}}' myFile 

它的工作原理不同的是,現在我要麼需要把一個空行或「N/A」,這樣的能力即使特定線路沒有與之關聯的用戶,我表格中的記錄也具有適當的值。這是我嘗試在其他情況下,添加:

awk '{for(i=1;i<=NF;i++){if($i~/^user/){print $i} else {print "stuff"}}}' myFile 

它的問題是,它看起來在每一個領域,並打印「N/A」的時候,我只希望它做一次,如果術語「用戶「在記錄行中找不到。我想過使用NR和NF做一個嵌套循環,但是我堅持認爲這看起來如何。

樣品輸入可以是:

status-code=32 action=add user=jim 
status-code=43 message=otherException 
status-code=32 action=add user=paul 
status-code=32 action=delete user=reggie 
status-code=2 action=endFile 

示例輸出將如下所示(我有另一段代碼,修剪「用戶=」位關閉後):

user=jim 
N/A 
user=paul 
user=reggie 
N/A 

在上面的例子中,上面的記錄沒有用戶的字段(他們可能是狀態消息或錯誤消息)。我不想跳過它們,而是想包括一個空白行或其他標記,以便在執行paste myfile myfile2 > myfile3命令時,即使不是每列都有用戶字段,列也會匹配。

回答

1

您需要設置一個標誌並僅在該標誌上打印「N/A」。事情是這樣的:

awk '{f=0;for(i=1;i<=NF;i++){if($i~/^user/){print $i;f=1}}if(!f){print "N/A"}}' myFile 

順便說一句,我更喜歡以避免不必要的大括號:

awk '{f=0; for (i=1;i<=NF;i++) if ($i~/^user/) {print $i; f=1} if (!f) print "N/A" }' myFile 

測試它使用您所提供的輸入:

$ cat file 
status-code=32 action=add user=jim 
status-code=43 message=otherException 
status-code=32 action=add user=paul 
status-code=32 action=delete user=reggie 
status-code=2 action=endFile 
$ awk '{f=0; for (i=1;i<=NF;i++) if ($i~/^user/) {print $i; f=1} if (!f) print "N/A" }' file 
user=jim 
N/A 
user=paul 
user=reggie 
N/A 

只是爲了好玩,下面是使用GNU awk解決問題的另一種方式(基於Ed的有用評論的編輯模式):

$ awk -v FPAT='user=\\S+' '{print NF ? $NF : "N/A"}' file 
user=jim 
N/A 
user=paul 
user=reggie 
N/A 

特殊變量FPAT用於描述字段的格式。這裏,模式與「user =」匹配,後跟一個或多個非空格字符\S+(必須轉義\,這就是爲什麼它是\\)。如果沒有字段與模式匹配,則NF爲0(即,假)並且打印「N/A」。否則,打印最後一個匹配字段。

當然,如果每個記錄可能有多個用戶,這不起作用,但從您的示例中可以看出,只有零個或一個。

+0

擁有最多1個用戶是正確的,是的。如果有兩個案例能幫助未來的人們看到這個問題,我想我可以再增加一個案例。 – Dumpcats

2
$ awk '{print (match($0,/user=[^ ]+/) ? substr($0,RSTART,RLENGTH) : "N/A")}' file 
user=jim 
N/A 
user=paul 
user=reggie 
N/A 
+0

也可以執行'awk'$ 0 = match($ 0,/ user = [^] + /,a)?a [0]:「N/A」。在評論中發表的評論與您的​​評論類似,以獲得新的答案。 – 123

+0

這將是gawk特定的,雖然禮貌第三arg匹配(),雖然我不反對gawk特定的答案時有用,我個人不覺得它在這種情況下足夠有用。當你知道你想要打印當前行時,我也不是一個依靠$ 0的值來調用默認行爲的巨大粉絲。 –

+0

夠公平的,每個人都有他們的偏好。只是覺得我會張貼它顯示不同/相似的方式:) – 123

1

我建議使用next聲明,如果你碰巧發現你用戶相匹配的領域。

awk '{for(i=1;i<=NF;i++){if($i~/^user/){print $i; next;}} print "N/A";}' myFile