在P1处的温度为35华氏度。
在P1处的温度为40华氏度。
在P3处的温度为35华氏度。
记录器停止。
记录器启动。
在P1处的温度为40华氏度。
并输出类似printf()的内容:
"The temperature at P%d is %dF.", Int1, Int2"
{(1,35), (1, 40), (3, 35), (1,40)}
该算法需要足够通用,能够识别消息组中几乎任何数据负载。
我尝试搜索这种技术,但我甚至不知道正确的术语去搜索。
在P1处的温度为35华氏度。
在P1处的温度为40华氏度。
在P3处的温度为35华氏度。
记录器停止。
记录器启动。
在P1处的温度为40华氏度。
并输出类似printf()的内容:
"The temperature at P%d is %dF.", Int1, Int2"
{(1,35), (1, 40), (3, 35), (1,40)}
该算法需要足够通用,能够识别消息组中几乎任何数据负载。
我尝试搜索这种技术,但我甚至不知道正确的术语去搜索。
我认为你可能忽视了fscanf()和sscanf()。它们是fprintf()和sprintf()的相反操作。
概述:
一个天真的算法以每列的方式跟踪单词的频率,其中可以假设每一行都可以用分隔符分成多列。
示例输入:
The dog jumped over the moon
The cat jumped over the moon
The moon jumped over the moon
The car jumped over the moon
频率:
Column 1: {The: 4}
Column 2: {car: 1, cat: 1, dog: 1, moon: 1}
Column 3: {jumped: 4}
Column 4: {over: 4}
Column 5: {the: 4}
Column 6: {moon: 4}
/The ([a-z]+?) jumps over the moon/
显然,第一遍可以选择扫描部分或整个文档,只要您确信频率列表将是整个数据的足够抽样。
假阳性可能会影响结果,过滤算法(手势)将提供静态和动态字段之间最佳阈值,或进行人工后处理。
总体想法可能是一个好想法,但实际实现肯定会影响此算法的速度和效率。
这取决于你想做什么,如果你的目标是快速生成sprintf()输入,那么这个方法可以使用。如果你想解析数据,也许正则表达式也可以完成。
你不可能找到一个工具,它可以简单地接受任意输入,猜测你想要的数据,并产生你想要的输出。对我来说,这听起来像是强人工智能。
即使只是识别数字,也会变得非常麻烦。例如,“123.456”是一个数字还是两个数字?“123,456”呢?“35F”是一个十进制数和一个“F”,还是16进制值0x35F?你必须构建一个按照你需要的方式进行解析的东西。你可以使用正则表达式完成这一点,或者你可以使用 sscanf
,或者你可以用其他方式,但你必须编写一些自定义代码。
然而,通过基本的正则表达式,你可以自己完成这个任务。虽然不会是魔法,但也不需要太多的工作量。像这样的 Perl 代码可以解析你感兴趣的行并将它们合并:
my @vals = ();
while (defined(my $line = <>))
{
if ($line =~ /The temperature at P(\d*) is (\d*)F./)
{
push(@vals, "($1,$2)");
}
}
print "The temperature at P%d is %dF. {";
for (my $i = 0; $i < @vals; $i++)
{
print $vals[$i];
if ($i < @vals - 1)
{
print ",";
}
}
print "}\n";
这个的输出是:
The temperature at P%d is %dF. {(1,35),(1,40),(3,35),(1,40)}
对于每种需要解析的行类型,您可以执行类似的操作。您甚至可以从文件中读取这些正则表达式,而不是自定义编码每个表达式。
我不知道有什么具体的工具可以做到这一点。当我遇到类似的问题需要解决时,我会尝试猜测正则表达式来匹配行。
然后我处理文件并仅显示未匹配的行。如果一行没有匹配成功,那么就意味着模式是错误的,应该进行调整或添加另一个模式。
经过大约一个小时的工作,我成功地找到了大约20个模式来匹配10000多行。
在您的情况下,您可以首先“猜测”一个模式是"P [1-3]处的温度为[0-9]{2}F。"
。如果您重新处理文件并删除任何匹配的行,则只剩下:
记录器停止。
记录器启动。
然后您可以使用"Logger (.+)."
与其匹配。
然后您可以完善模式并找到新的模式来匹配整个日志。
http://www.logparser.com 转到一个似乎相当活跃的 IIS 论坛。这是 Gabriele Giuseppini 的“Log Parser Toolkit”的官方网站。虽然我实际上从未使用过这个工具,但我在 Amazon Marketplace 上购买了一本便宜的书 - 现在一本只要 16 美元。对于翻阅页面来说,没有什么比纸质书更好的了。
浏览这个论坛时,我之前没有听说过“MS Log Parser 的新 GUI 工具 Log Parser Lizard”,位于 http://www.lizardl.com/。
当然,关键问题是你的 GRAMMAR 复杂性。使用任何常用术语中的日志分析器,您需要确切地知道您正在扫描什么,您可以写出一个 BNF。多年前,我参加了一门基于 Aho 和 Ullman 的“龙书”教程,彻底理解的 LALR 技术可以为您提供最佳速度,当然前提是您拥有该 CFG。
另一方面,似乎您可能会寻找某种类似 AI 的东西,这完全是不同层次的复杂性。
@John:我认为这个问题涉及到一种能够识别日志文件中模式并自动“猜测”适当格式字符串和数据的算法。 *scanf
系列本身无法完成此任务, 它只能在首次识别模式后提供帮助。
@Derek Park:即使是强大的人工智能也不能确定它有正确的答案。
也许可以使用一些类似于压缩的机制:
另一个要考虑的问题可能是按 编辑距离 分组行。将相似的行分组应该将问题分成每组一个模式的块。
实际上,如果你成功地写出了这个工具,让全世界都知道,我想我们很多人都会喜欢这个工具!
@Anders
即使是强人工智能也不能确定它有正确的答案。
我认为足够强大的人工智能通常可以从上下文中找到正确的答案。例如,强人工智能可以识别出这种情况下的“35F”是温度而不是十六进制数。当然,还有一些情况即使是强人工智能也无法回答。但这些情况对于人类来说也是一样的(假设非常强大的人工智能)。
当然,由于我们没有强人工智能,所以这并不重要。 :)