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

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

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

谢谢。

答案1

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] }'

这使用 gnu awk 的split()函数和正则表达式将行分成 3 部分: 中匹配之前的部分d[1]、 中匹配之后的部分以及s[1] 中d[2]匹配的字符串。"/49,"您确实应该检查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 }'

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

相关内容