【发布时间】:2014-10-08 22:13:41
【问题描述】:
我有一个 awk 脚本,当我将正则表达式放在不同的地方时,它的行为会有所不同。显然,我使程序的逻辑在两种情况下都可以正常工作,但事实并非如此。该脚本用于分析每个事务具有唯一 ID 的一些日志。日志看起来像
timestamp (ID) more info
例如:
2014-10-06 05:24:40,035 INFO (4aaaaaaaaabbbbbbcccb) [somestring] body with real information and a key string that determines the type of thransaction
2014-10-06 05:24:40,035 INFO (4aaaaaaaaabbbbbbcccb) [somestring] body with other information
2014-10-06 05:24:40,035 INFO (4aaaaaaaaabbbbbbcccb) [somestring] body with more information
2014-10-06 05:24:40,035 INFO (4xxbbbbbbbbbbbbbcccb) [somestring] this is a different transaction
我想要的是处理某种事务的所有日志行,看看它们需要多少时间。每个事务都分布在多个日志行中,并由其唯一 ID 标识。要知道某个交易是否属于我想要的类型,我必须在该交易的第一行中搜索某个字符串。日志中可能有没有上述格式的行。
我想要什么:
- 区分当前行是否是事务的一部分(它有一个 ID)
- 检查 ID 是否已在累积数组中注册。
- 如果不是,请检查它是否属于所需类型:在行的正文中搜索固定字符串。
- 如果是,注册时间戳,然后等等等等
这是代码(注意这是一个非常缩小的版本)。
这是我想用的,先检查是否是事务行,然后检查是否是正确的类型
awk '$4 ~ /^\([:alnum:]/
{
name=$4;gsub(/[()]|:.*/,"",name);++matched
if(!(name in arr)){
if($0 ~ /transaction type/){arr[name]=1;print name}}
}END
{
print "Found :"length(arr)
print "Processed "NR
print matched" lines matched the filter"
}'
该脚本仅找到 868 个事务,其中一些事务超过 14K。如果我将脚本更改为如下代码,如果找到所有 14k 事务,但只找到所有事务的第一行,那么它对我没有用。
awk '/transaction type/
{
name=$4;gsub(/[()]|:.*/,"",name);++matched
if(!(name in arr)){
arr[name]=1;print name
}
}END
{
print "Found :"length(arr)
print "Processed "NR
print matched" lines matched the filter"
}'
提前致谢。
编辑
真丢脸。这个话题有不止一个实际问题。 主要问题是正则表达式与正确的字符串不匹配。 ID 字符串和交易字符串的类型在同一行,这是真的,但在那些行上,ID 就像 (aaaaaabbbbbcccc: ),末尾有两个空格。这使得 AWK 解析 "(aaaaaaaaabbbbcccc:" 和 ")" 作为两个不同的字段。当我这样做时我意识到了
$4 !~ /regex/ print $4
然后出现了很多有效的ID。
修复正则表达式后出现的第二个问题在这里已经有人解决了。将主正则表达式和第一个 { 放在分开的行中使 awk 可以打印每条记录。我意识到我自己和同一天后我在这里阅读了解决方案。太棒了。
非常感谢大家。我只能接受一个有效的答案,但我从他们所有人身上学到了很多。
【问题讨论】:
-
您可以考虑使用带有 grok 和多行过滤器的 logstash 来完成此类工作。我很不确定您输入的内容是什么样的,因为您的示例中只有一种行格式。
-
你好。我无法安装比可用程序更多的程序。我只对与所描述格式匹配的行感兴趣,所以 IMO 没有问题。我不知道所有的线条是什么样子的,但这根本不重要。
-
/transaction type/与您输入的任何示例行都不匹配。这使得很难确定可能出了什么问题。你能给我们实际的日志行和你匹配的实际字符串/正则表达式吗? -
请提供真实输入的摘录,没有那种交易类型很难理解。我会根据我的理解尝试回答,但我不确定。