gawk 中的“^ 反斜杠不是最后一个字符”

Tim*_*Tim 1 awk gawk

我想在每行之间/,中匹配一个数字,并将其增加 3。例如

无处不在的反斜杠/49,黑色

变成

无处不在的反斜杠/52,黑色

我的 gawk 命令是:

$ gawk '{b=gensub(/\/([0-9]+),/, "/" (\\1+3) ",") ; print b}' add.jpdf 
gawk: cmd. line:1:                    ^ backslash not last character on line
Run Code Online (Sandbox Code Playgroud)

我想知道“^ 反斜杠不是最后一个字符”是什么意思?我的解决方案违反了哪个 gawk 语法规则?

谢谢。

meu*_*euh 5

gensub()需要一个字符串作为第二个参数。您正在尝试连接/,围绕(\\1+3)您假设将由函数评估的表达式。它不会。它在调用函数之前被评估。用于在正则表达式中\1引用匹配的捕获组(),但只能在字符串中使用,而不能在表达式中使用。

所以充其量你可以使用作为第二个参数"/\\1+3,",但你会得到结果...Backslash/49+3,Black。您不能以这种方式评估 49+3 部分。

如果要对匹配进行算术运算,则必须先提取字符串,进行算术运算,然后将其放回字符串中。例如,

awk '{ n = split($0, d, /\/([0-9]+),/, s)
       print d[1] "/"(substr(s[1],2)+3)"," d[2] }'
Run Code Online (Sandbox Code Playgroud)

这使用split()带有正则表达式的gnu awk函数将行分成 3 部分:匹配之前d[1]的部分,匹配之后的部分d[2],以及"/49,"s[1] 中匹配的字符串。你真的应该检查nis 2 以确保你得到了一场比赛。

然后,您可以通过简单地跳过初始"/",进行算术,然后再次将所有部分连接在一起,从匹配的字符串中提取数字。


如果该模式可能在您的数据的一行中出现多次,更好的解决方案是使用match()仅查找最后一次出现并使用substr()以下命令剪切该行:

awk '{ match($0, /.*\/([0-9]+),/, m)
       a = m[1,"start"]
       b = m[1,"length"]
       if(a)print substr($0,1,a-1) substr($0,a,b)+3 substr($0,a+b)
       else print }'
Run Code Online (Sandbox Code Playgroud)

此处模式已.*添加到前面以仅匹配最后一次出现。 a被设置为正()则表达式中捕获组开始的字符位置b及其长度,因此substr($0,a,b)只是数字。最后一行是从原始数据的另外两个部分重新组合而成的。