【问题标题】:awk regex: difference between using it or without variablesawk 正则表达式:使用它或不使用变量之间的区别
【发布时间】: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/ 与您输入的任何示例行都不匹配。这使得很难确定可能出了什么问题。你能给我们实际的日志行和你匹配的实际字符串/正则表达式吗?
  • 请提供真实输入的摘录,没有那种交易类型很难理解。我会根据我的理解尝试回答,但我不确定。

标签: regex bash awk


【解决方案1】:

空格在 awk 中很重要。这个:

/foo/ {
    print "found"
}

表示print 'found' every time "foo" is present,而这个:

/foo/
{
    print "found"
}

表示print the current record every time "foo" is present and print "found" for every single input record,所以你写的时候很有可能:

$4 ~ /^\([:alnum:]/
{
     ....
}

你实际上是想写:

$4 ~ /^\([:alnum:]/ {
     ....
}

另外,您可能打算使用 POSIX 字符类 [[:alnum:]] 而不是字符集 [ : a l n u m 所描述的字符集 [:alnum:]

$4 ~ /^\([[:alnum:]]/ {
     ....
}

如果您解决了这些问题但仍需要帮助,请提供一些可测试的示例输入和预期输出,我们可以为您提供更多帮助。

【讨论】:

  • 对于换行,我确实认为为了便于阅读而在此处发布格式是一种努力,但值得注意的是。我在爆炸我的例子时犯了同样的错误:)
【解决方案2】:

这只是一个语法错误。当您使用 posix 字符类时,您必须将其括在方括号中:

[[:alnum:]]

否则[:alnum:] 被视为包含: a l m n u 的字符类

【讨论】:

    【解决方案3】:

    简而言之,如果我理解正确,您希望获得某种交易类型的 id。

    第一个假设:id 和事务类型在同一行,应该这样做(很大程度上改编自您的代码)

    awk 'BEGIN {
      matched=0 # more for clarity than really needed
    }
    /\([[:alnum:]]*\).*transaction type/ { # get lines matching the id and the transaction only
      gsub(/[()]/,"",$4) # strip the () around the id
      ++matched # to get the number of matched lines including the multiples ones.
      if (!($4 in arr)) { # as yours, if the id is not in array
        arr[$4]=1 # add the found id to array for no including it twice
        print $4 # print the found id (only once as we're in the if
      }
    }
    END { # nothing changed here, printing the stats...
      print "Found :"length(arr)
      print "Processed "NR
      print matched" lines matched the filter"
    }'
    

    您的示例输入的输出:

    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
    

    我在测试中省略了交易,因为我不知道它可能是什么

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 2013-09-18
      • 2012-07-17
      • 2016-11-18
      • 2012-02-22
      • 2023-04-07
      • 2011-01-14
      相关资源
      最近更新 更多