我需要处理一个非常大的日志文件,其中包含许多不同格式的行。
我的目标是提取具有相同起始模式的唯一行条目,例如“^2011-02-21.*MyKeyword.*Error”,有效地获取每个行模式的样本列表,从而识别模式。
到目前为止我只知道一些模式,手动浏览文件绝对不是一个选择。
请注意,除了已知的模式外,还有许多未知的模式,我也想自动提取这些模式。
做这个的最好方式是什么?我确实很了解正则表达式,但还没有对 awk/sed 做太多工作,我想在这个过程中的某个时刻会使用它们。
答案1
如果我理解正确的话,你有一堆模式,并且你想为每个模式提取一个匹配项。下面的 awk 脚本应该可以解决这个问题。它打印给定模式的第一次出现,并记录已看到的模式,以便不打印后续出现的情况。
awk '
/^2011-02-21.*MyKeyword.*Error/ {
if (!seen["^2011-02-21.*MyKeyword.*Error"]++) print;
next;
}
1 {if (!seen[""]++) print} # also print the first line that matches no pattern
'
MyKeyword.*Error
这是每天保留一行的变体。
awk '
/^[0-9]{4}-[0-9]{2}-[0-9]{2}.*MyKeyword.*Error/ {
if (!seen[substr($0,10) "MyKeyword.*Error"]++) print;
next;
}
'
答案2
目前尚不清楚您是否正在尝试按以下方式对线路进行分组未知的输出模式或者已知模式中的未知关键字。
在第一种情况下,如果您有如下日志:
[2010-04-02 12:00:00] Error: BaseController Something went wrong
2010-04-02 12:01:00 Warning - Something happened
UserController (2010-04-02 12:02:00) failed with exit status: 1
[2010-04-02 12:03:00] Error: BaseController Something went wrong
[2010-04-02 12:04:00] Error: BaseController Something went wrong
2010-04-02 12:04:01 Warning - Something else happened
UserController (2010-04-02 12:05:00) failed with exit status: 2
UserController (2010-04-02 12:06:00) failed with exit status: 10
那么你可以使用tr
andsort
和/或uniq
来探索模式:
$ tr '[:alpha:]' x < file.log | tr '[:digit:]' d | sort -u
dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxxxxxx
dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxx xxxxxxxx
[dddd-dd-dd dd:dd:dd] xxxxx: xxxxxxxxxxxxxx xxxxxxxxx xxxx xxxxx
xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: d
xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: dd
或者,如果您想计算出现次数:
$ tr '[:alpha:]' x < file.log | tr '[:digit:]' d | sort | uniq -c
1
1 dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxxxxxx
1 dddd-dd-dd dd:dd:dd xxxxxxx - xxxxxxxxx xxxx xxxxxxxx
3 [dddd-dd-dd dd:dd:dd] xxxxx: xxxxxxxxxxxxxx xxxxxxxxx xxxx xxxxx
2 xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: d
1 xxxxxxxxxxxxxx (dddd-dd-dd dd:dd:dd) xxxxxx xxxx xxxx xxxxxx: dd
但如果模式始终相同,例如我的关键字总是在同一个地方(例如[2010-04-02 12:00:00] Error: BaseController Something went wrong
),但您想找出该位置可能有哪些字符串,您只需:
$ awk '{a[$3]++} END {for (i in a) {printf("%4d %s\n", a[i], i) } }' file.log
这应该给你类似的东西
3 Error
1 Info
2 Warning