2012-04-06 71 views
0

我必須從大日誌文件行解析某些信息。 它像使用awk解析日誌行

abc.log:2012-03-03 11:12:12,457 ABC[123.RPH.-101] XYZ: Query=get_data @a=0,@b=1 Rows=10Time=100 

有許多日誌行像上面的日誌文件。我需要提取信息,如 日期時間即2012-03-03 11:12:12,457 工作細節,即123.RPH.-101 查詢即GET_DATA(無參數) 行,即10 時間,即100

所以輸出應該像

2012-03-03 11:12:12,457|123|-101|get_data|10|100 

我曾嘗試使用awk各種排列計算,但沒有得到它的權利。

+0

我只希望'行數= 10時間= 100'原本是爲'行= 10時間= 100'。 – C2H5OH 2012-04-06 19:37:24

+0

在日誌文件中是「abc.log:」還是grep輸出? – 2012-04-06 20:42:20

回答

1

好了,這是很可怕的,但因爲sed是在標籤和沒有解答...

sed -e 's/[^0-9]*//' -re 's/[^ ]*\[([^.]*)\.[^.]*\.([^]]*)\]/| \1 | \2/' -e 's/[^ ]* Query=/| /' -e 's/ [^ ]* Rows=/ | /' -e 's/Time=/ | /' my_logfile 
1

TXR:

@(collect :vars()) 
@file:@[email protected]@day @hh:@mm:@ss,@ms @jobname[@[email protected]] @queryname: [email protected] @params [email protected]{rows /[0-9]+/}[email protected] 
@(output) 
@[email protected]@day @[email protected]@ss,@ms|@job1|@job2|@query|@rows|@time 
@(end) 
@(end) 

運行:

$ txr data.txr data.log 
2012-03-03 11-12-12,457|123|-101|get_data|10|100 

這是一種使程序斷言日誌文件中的每一行都必須匹配模式的方法。首先,不要在收藏中留下空白。這意味着,不匹配的材料不能被跳過只尋找符合該行:

@(collect :gap 0 :vars()) 

其次,在腳本的末尾,我們補充一點:

@(eof) 

這指定在結束比賽的文件。如果@(collect)由於不匹配的行(由於:gap 0約束條件)而提早提早提取,@(eof)將會失敗,因此腳本將以失敗狀態終止。

在這種類型的任務中,字段拆分正則表達式hacks將會適得其反,因爲它們可能會盲目地爲正在處理的輸入的某個子集產生不正確的結果。如果輸入包含大量的行,則沒有簡單的方法來檢查錯誤。最好有一個非常具體的匹配,可能會拒絕任何與模式基於的示例不相似的東西。

+0

這個工具/語言看起來非常有趣。感謝您發佈此信息。 – 2012-04-06 19:50:12

+0

請注意,'Rows = 10Time = 100'的處理與問題中指定的相同。這是我們有理由達成正則表達式的一個很好的例子。 – Kaz 2012-04-06 20:52:49

1

我在gawk中的解決方案:它使用gawk擴展來匹配。

你沒有給出文件格式的規範,所以你可能不得不調整正則表達式。

腳本調用: gawk -v OFS='|' -f script.awk

{ 
match($0, /[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+,[0-9]+/) 
date_time = substr($0, RSTART, RLENGTH) 

match($0, /\[([0-9]+).RPH.(-?[0-9]+)\]/, matches) 
job_detail_1 = matches[1] 
job_detail_2 = matches[2] 

match($0, /Query=(\w+)/, matches) 
query = matches[1] 

match($0, /Rows=([0-9]+)/, matches) 
rows = matches[1] 

match($0, /Time=([0-9]+)/, matches) 
time = matches[1] 

print date_time, job_detail_1, job_detail_2, query,rows, time 
} 
1

這裏有一個不太花哨,AWK溶液(但mawk太工作):

BEGIN { OFS="|" } 

{ 
    i = match($3, /\[[^]]+\]/) 
    job = substr($3, i + 1, RLENGTH - 2) 
    split($5, X, "=") 
    query = X[2] 
    split($7, X, "=") 
    rows = X[2] 
    split($8, X, "=") 
    time= X[2] 

    print $1 " " $2, job, query, rows, time 
} 

Nothe這個假設Rows=10Time=100字符串分隔通過空間,也就是說,在問題示例中存在拼寫錯誤。

0

只需要正確的字段分隔

awk -F '[][ =.]' -v OFS='|' '{print $1 " " $2, $4, $6, $10, $15, $17}' 

我假設「abc.log:」實際上不是在日誌文件中。