Regex awk正则表达式:使用它与不使用变量之间的区别
我有一个awk脚本,当我在不同的地方放置正则表达式时,它的行为会有所不同。显然,我让程序的逻辑在这两种情况下都是一样的,但事实并非如此。该脚本用于分析一些日志,其中每个事务都有一个唯一的IDRegex awk正则表达式:使用它与不使用变量之间的区别,regex,bash,awk,Regex,Bash,Awk,我有一个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 determine
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。如果我更改脚本,使其看起来像下面的代码,那么If会找到所有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类似(aaaaaa bbbbb cccc:),末尾有两个空格。这使得AWK无法解析
“(AAAAA BBBBCCCC:“和”)“作为两个不同的字段。我意识到了
$4 !~ /regex/ print $4
并且出现了很多有效的ID
第二个问题是在修复正则表达式后出现的,这里的一些人已经解决了这个问题。把主正则表达式和第一行分开,可以打印每一条记录。我意识到我自己和当天之后我在这里读到了解决方案。太棒了
非常感谢各位。我只能接受一个有效答案,但我从所有答案中学到了很多。这只是语法错误。使用posix字符类时,必须将其括在方括号内:
[[:alnum:]]
否则,
[:alnum://code>被视为包含:lamn u
的字符类,这只是语法错误。使用posix字符类时,必须将其括在方括号内:
[[:alnum:]]
否则,[:alnum://code>被视为一个字符类,其中包含:lamnu
因此,简单地说,如果我理解正确,您希望获得特定类型事务的ID
第一个假设:id和事务类型在同一行,类似的事情应该可以做到(主要是根据您的代码改编)
从您的示例输入中输出:
prompt=> awk 'BEGIN { matched=0}; / \([a-z0-9]*\) / { gsub(/[()]/,"",$4); ++matched; if (!($4 in arr)) { arr[$4]=1; print $4 }}; END { print "Found: "length(arr)"\nProcessed "NR"\n"matched" lines matched the filter" }' awkinput
4aaaaaaaaabbbbbbcccb
4xxbbbbbbbbbbbbbcccb
Found: 2
Processed 4
4 lines matched the filter
我在测试中输入了该事务,因为我不知道它可能是什么,因此简单地说,如果我理解正确,您希望获得特定类型事务的ID
第一个假设:id和事务类型在同一行,类似的事情应该可以做到(主要是根据您的代码改编)
从您的示例输入中输出:
prompt=> awk 'BEGIN { matched=0}; / \([a-z0-9]*\) / { gsub(/[()]/,"",$4); ++matched; if (!($4 in arr)) { arr[$4]=1; print $4 }}; END { print "Found: "length(arr)"\nProcessed "NR"\n"matched" lines matched the filter" }' awkinput
4aaaaaaaaabbbbbbcccb
4xxbbbbbbbbbbbbbcccb
Found: 2
Processed 4
4 lines matched the filter
我在测试中记录了该事务,因为我不知道它在awk中可能是什么。这是:
/foo/ {
print "found"
}
表示每次出现“foo”时打印“found”
,同时:
/foo/
{
print "found"
}
意味着每次“foo”出现时打印当前记录,并为每个输入记录打印“found”
,因此,当您写入以下内容时:
$4 ~ /^\([:alnum:]/
{
....
}
你真的想写:
$4 ~ /^\([:alnum:]/ {
....
}
此外,您可能打算使用POSIX字符类[:alnum:]
,而不是字符集[:a l n u m
所描述的字符集[:alnum:]
:
$4 ~ /^\([[:alnum:]]/ {
....
}
如果您解决了这些问题,但仍然需要帮助,请提供一些可测试的示例输入和预期输出,我们可以为您提供更多帮助。在awk中,空白区域很重要。这:
/foo/ {
print "found"
}
表示每次出现“foo”时打印“found”,同时:
/foo/
{
print "found"
}
意味着每次“foo”出现时打印当前记录,并为每个输入记录打印“found”,因此,当您写入以下内容时:
$4 ~ /^\([:alnum:]/
{
....
}
你真的想写:
$4 ~ /^\([:alnum:]/ {
....
}
此外,您可能打算使用POSIX字符类[:alnum:]
,而不是字符集[:a l n u m
所描述的字符集[:alnum:]
:
$4 ~ /^\([[:alnum:]]/ {
....
}
如果你修复了这些东西,你仍然需要帮助,提供一些可测试的样本输入和预期输出。我们可以帮助你更多。
你可以考虑使用LogStask与GROK和多行过滤器进行这类工作。我很不确定你输入的是什么样的,因为在你的示例中只有一种格式的线。你好。我不能安装更多的PRO。克。我只对与所述格式匹配的行感兴趣,因此在我看来没有问题。我不知道所有行的外观如何,但这一点都不重要。/transaction type/
与您的任何输入示例行都不匹配。这使得很难确定可能有什么错误。您能给我们提供实际的吗日志行和你正在匹配的实际字符串/ReGEX?请给出一个实际输入的摘录,没有这种交易类型是很难理解的。我会尝试对我所理解的答案,但我不确定。你可以考虑使用LogStAg与GROK和多行过滤器来进行这类工作。我很不确定你输入的东西看起来像T。在你的例子中,这里只有一种行的格式。你好。我不能安装比可用的更多的程序。我只对