awk从每一行中提取多个组

时间:2009-07-12 15:08:08

标签: regex awk grouping

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

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

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

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

200
400
0

4 个答案:

答案 0 :(得分:11)

这是一个简单的语法,每个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);
    }
}

答案 1 :(得分:2)

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

 {
     pattern = "([a-g]+|[h-z]+)"
     while (match($0, pattern, arr))
     {
         val = arr[1]
         print val
         sub(pattern, "")
     }
 }

答案 2 :(得分:1)

GNU awk

awk 'BEGIN{ RS="Hello! ";}
{
    gsub(/[^0-9].*/,"",$1)
    if ($1 != ""){ 
        print $1 
    }
}' file

答案 3 :(得分: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