10

当模式在一行中多次匹配时,如何对所有匹配组执行操作?

为了说明,我想搜索/Hello! (\d+)/并使用数字,例如,将它们打印出来或将它们相加,所以输入

abcHello! 200 300 Hello! Hello! 400z3
ads
Hello! 0

如果我决定将它们打印出来,我希望输出

200
400
0
4

4 回答 4

13

这是一个简单的语法,每个 awk(nawk、mawk、gawk 等)都可以使用它。

{
    while (match($0, /Hello! [0-9]+/)) {
        pattern = substr($0, RSTART, RLENGTH);
        sub(/Hello! /, "", pattern);
        print pattern;
        $0 = substr($0, RSTART + RLENGTH);
    }
}
于 2009-07-13T09:54:29.943 回答
2

这是gawk语法。当没有可以用作记录分隔符并且不匹配换行符的固定文本时,它也适用于模式:

 {
     pattern = "([a-g]+|[h-z]+)"
     while (match($0, pattern, arr))
     {
         val = arr[1]
         print val
         sub(pattern, "")
     }
 }
于 2009-07-12T16:20:03.713 回答
1

GNU awk

awk 'BEGIN{ RS="Hello! ";}
{
    gsub(/[^0-9].*/,"",$1)
    if ($1 != ""){ 
        print $1 
    }
}' file
于 2009-07-12T15:31:22.907 回答
0

没有 gawk 函数可以在一行中多次匹配相同的模式。除非您确切知道该模式重复了多少次。

有了这个,您必须在同一行中的所有匹配项上“手动”迭代。对于您的示例输入,它将是:

{
  from = 0
  pos = match( $0, /Hello! ([0-9]+)/, val )
  while( 0 < pos )
  {
    print val[1]
    from += pos + val[0, "length"]
    pos = match( substr( $0, from ), /Hello! ([0-9]+)/, val )
  }
}

如果模式应通过换行符匹配,则必须修改输入记录分隔符 - RS

于 2009-07-27T07:05:49.860 回答