我必须从大日志文件行中解析一些信息。 它的类似
abc.log:2012-03-03 11:12:12,457 ABC[123.RPH.-101] XYZ: Query=get_data @a=0,@b=1 Rows=10Time=100
日志文件中有如上所示的许多日志行。我需要提取信息 datetime ie 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 :(得分:1)
嗯,这真的太可怕了,但是因为sed
在标签中并且还没有答案......
sed -e 's/[^0-9]*//' -re 's/[^ ]*\[([^.]*)\.[^.]*\.([^]]*)\]/| \1 | \2/' -e 's/[^ ]* Query=/| /' -e 's/ [^ ]* Rows=/ | /' -e 's/Time=/ | /' my_logfile
答案 1 :(得分:1)
TXR:
@(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)
将失败,因此脚本将以失败状态终止。
在这种类型的任务中,字段拆分正则表达式攻击会适得其反,因为它们可能会盲目地为正在处理的输入的某个子集产生不正确的结果。如果输入包含大量行,则没有简单的方法来检查错误。最好有一个非常具体的匹配,可能会拒绝任何与模式所基于的示例不相似的东西。
答案 2 :(得分: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
}
答案 3 :(得分: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
}
请注意,这假设Rows=10
和Time=100
字符串由空格分隔,即问题示例中存在拼写错误。
答案 4 :(得分:0)
只需要正确的字段分隔符
awk -F '[][ =.]' -v OFS='|' '{print $1 " " $2, $4, $6, $10, $15, $17}'
我假设“abc.log:”实际上并不在日志文件中。