当模式在一行中多次匹配时,如何对所有匹配组执行操作?
为了说明,我想搜索/Hello! (\d+)/
并使用数字,例如,将它们打印出来或将它们相加,所以输入
abcHello! 200 300 Hello! Hello! 400z3
ads
Hello! 0
如果我决定将它们打印出来,我希望输出
200
400
0
这是一个简单的语法,每个 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);
}
}
这是gawk
语法。当没有可以用作记录分隔符并且不匹配换行符的固定文本时,它也适用于模式:
{
pattern = "([a-g]+|[h-z]+)"
while (match($0, pattern, arr))
{
val = arr[1]
print val
sub(pattern, "")
}
}
GNU awk
awk 'BEGIN{ RS="Hello! ";}
{
gsub(/[^0-9].*/,"",$1)
if ($1 != ""){
print $1
}
}' file
没有 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