0

我必须从大日志文件行中解析一些信息。它就像

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 尝试了各种排列计算,但没有得到正确的结果。

4

5 回答 5

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
}
于 2012-04-06T19:42:16.553 回答
1

好吧,这真的很可怕,但是因为sed在标签中并且还没有答案......

sed -e 's/[^0-9]*//' -re 's/[^ ]*\[([^.]*)\.[^.]*\.([^]]*)\]/| \1 | \2/' -e 's/[^ ]* Query=/| /' -e 's/ [^ ]* Rows=/ | /' -e 's/Time=/ | /' my_logfile
于 2012-04-06T19:28:45.317 回答
1

发射器:

@(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)则将失败,因此脚本将以失败状态终止。

在这种类型的任务中,字段拆分正则表达式黑客会适得其反,因为它们会盲目地为正在处理的输入的某些子集产生不正确的结果。如果输入包含大量行,则没有简单的方法来检查错误。最好有一个非常具体的匹配,它可能会拒绝任何与模式所基于的示例不相似的东西。

于 2012-04-06T19:34:26.493 回答
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=10Time=100字符串用空格分隔,也就是说,问题示例中有一个错字。

于 2012-04-06T19:44:34.140 回答
0

只需要正确的字段分隔符

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

我假设“abc.log:”实际上不在日志文件中。

于 2012-04-06T20:48:13.327 回答