示例:应用程序生成包含许多不同消息的大型文本日志文件。当无法正常运行时,A
它也会生成类似的大型日志文件。B
我想查看文件中哪些消息B
本质上是新的,即从中过滤掉所有内容A
。
简单原型是:
- 对两个文件进行排序 | uniq
- 连接文件
- 排序 | uniq-c
- grep -v "^2"
这样就产生了对称差异,很不方便。如何做得更好?(包括非对称差异和保留消息顺序B
)
程序应该首先分析A
了解哪些消息是常见的,然后分析B
显示需要注意的消息。
理想情况下,它应该自动忽略时间戳、行号或其他易变的东西。
例如。答:
0:00:00.234 Received buffer 0x324234
0:00:00.237 Processeed buffer 0x324234
0:00:00.238 Send buffer 0x324255
0:00:03.334 Received buffer 0x324255
0:00:03.337 Processeed buffer 0x324255
0:00:03.339 Send buffer 0x324255
0:00:05.171 Received buffer 0x32421A
0:00:05.173 Processeed buffer 0x32421A
0:00:05.178 Send buffer 0x32421A
乙:
0:00:00.134 Received buffer 0x324111
0:00:00.137 Processeed buffer 0x324111
0:00:00.138 Send buffer 0x324111
0:00:03.334 Received buffer 0x324222
0:00:03.337 Processeed buffer 0x324222
0:00:03.338 Error processing buffer 0x324222
0:00:03.339 Send buffer 0x3242222
0:00:05.271 Received buffer 0x3242FA
0:00:05.273 Processeed buffer 0x3242FA
0:00:05.278 Send buffer 0x3242FA
0:00:07.280 Send buffer 0x3242FA failed
结果:
0:00:03.338 Error processing buffer 0x324222
0:00:07.280 Send buffer 0x3242FA failed
解决这个问题的方法之一可能是这样的:
- 将每行拆分为逻辑单元:
0:00:00.134 Received buffer 0x324111
,0:00:00.134
,Received
,buffer
,0x324111
,324111
,Received buffer
,\d:\d\d:\d\d\.\d\d\d
,\d+:\d+:\d+.\d+
,0x[0-9A-F]{6}
... 它应该找到单个单词、数字中的简单模式、常见布局(例如“某些日期比文本比数字比文本比行尾”),还可以处理上述组合。由于这不是一项简单的任务,因此应该支持(但不是必需的)用户帮助(添加具有明确“忽略那个”、“作为主要因素”、“不要拆分为部分”、“视为日期/数字”、“注意此类消息的顺序/数量”规则的正则表达式)。 - 查找重复的单元并“分类”行,过滤掉过于不稳定的内容,例如时间戳、地址或行号。
- 分析第二个文件,找到具有新逻辑单元(一次性或重复性)的东西,或者任何会让已经习惯第一个文件的系统“惊奇”的东西。
手动执行一些此类操作的示例:
$ cat A | head -n 1
0:00:00.234 Received buffer 0x324234
$ cat A | egrep -v "Received buffer" | head -n 1
0:00:00.237 Processeed buffer 0x324234
$ cat A | egrep -v "Received buffer|Processeed buffer" | head -n 1
0:00:00.238 Send buffer 0x324255
$ cat A | egrep -v "Received buffer|Processeed buffer|Send buffer" | head -n 1
$ cat B | egrep -v "Received buffer|Processeed buffer|Send buffer"
0:00:03.338 Error processing buffer 0x324222
0:00:07.280 Send buffer 0x3242FA failed
这是一件很无聊的事情(有很多消息类型);而且我可能会不小心包含一些太宽泛的模式。而且它无法处理消息之间的相互关系等复杂的事情。
我知道这是与人工智能相关的。可能已经开发出工具了?
答案1
diff
(及其各种选项)将向您显示两种方式的差异,并保留消息顺序。但是,它不会删除差异的重复项(因为您可以uniq
在之后应用)或处理不同的顺序。这样够好吗?
答案2
使用diff
(在正常输出模式下,即没有-c
或-u
)。新行将以 为前缀>
。
diff A B | sed -ne 's/> //p'
如果日志包含时间戳,则必须先将其删除。
有时,在上下文中查看新/更改的部分会更好,突出显示差异并导航不同的块。Emacs 有一个不错的界面(工具 | 比较菜单,M-x ediff-files
)。还有许多独立工具(名称中通常带有“diff”或“compare”)。
顺便说一句,如果您对行的顺序不感兴趣,那么对两个文件进行排序comm
会比您在问题中给出的过程更容易、更漂亮。
答案3
这是一个难题,从某种意义上说,也是一个活跃的研究问题。我认为目前还没有一个程序只需要插入几个正则表达式即可。
我会将您的程序表述为尝试比较网络程序的踪迹。我怀疑比较网络或并发程序踪迹的人遇到过这个问题并编写了自己的工具,但我脑子里没有具体的例子。