我想在每行之间/
和,
每行中匹配一个数字,并将其增加 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,"
您确实应该检查n
is 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)
只是数字。最后一行是由原始数据的其他两个部分重新组合而成的。