簡體   English   中英

使用 awk 解析日志行

[英]Parsing log lines using 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

所以 output 應該是這樣的

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

我用 awk 嘗試了各種排列計算,但沒有得到正確的結果。

好吧,這真的很糟糕,但是由於sed在標簽中並且還沒有答案......

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

發射機:

@(collect :vars ())
@file:@year-@mon-@day @hh:@mm:@ss,@ms @jobname[@job1.RPH.@job2] @queryname: Query=@query @params Rows=@{rows /[0-9]+/}Time=@time
@(output)
@year-@mon-@day @hh-@mm-@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 會適得其反,因為它們可能會盲目地為正在處理的輸入的某些子集產生不正確的結果。 如果輸入包含大量行,則沒有簡單的方法來檢查錯誤。 最好有一個非常具體的匹配,它可能會拒絕任何與模式所基於的示例不相似的內容。

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

您沒有指定文件格式,因此您可能需要調整正則表達式。

腳本調用: gawk -v OFS='|' -f script.awk 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
}

這是另一個不那么花哨的 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
}

但這假定Rows=10Time=100字符串由空格分隔,也就是說,問題示例中有錯字。

只需要正確的字段分隔符

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

我假設“abc.log:”實際上不在日志文件中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM