https://stackoverflow.com/a/14348899/15603477
我确实理解以下答案。
sed -r 's/(.*)(\?cache_version=)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' file
但我想知道如何在 awk 中做到这一点。
转换barbaz?cache_version=3fooooo
为barbaz?cache_version=4fooooo
文件test1
内容为
ello
barbaz?cache_version=3fooooo
bye
条件是找到包含的行,cache_version=
然后将匹配行中的数值加1。
我什至找不到匹配的数值,更不用说增加数值了。
到目前为止我只通过以下方式找到特定行
awk '{if(/cache_version=([[:digit:]+])/) print $1}' < test1
答案1
假设数字始终是整数:
awk 'BEGIN{ FS=OFS="=" }
/cache_version/{ match($NF, /^[0-9]+/); $NF=($NF+1) substr($NF, RLENGTH+1) }1' infile
在 BEGIN{} 块中我们设置输入F产量S分离器以及氧输出F产量S分隔符到单个相等=
字符;
那么我们在这里做的是awk '/pattern-matching(regexp)/ { "actions" }
,块中的哪些操作{...}
将仅针对与正则表达式匹配的行运行cache_version
;
这match(s, r [, a]) 函数,返回位置s
其中正则表达式r
发生,或为零,如果r
不存在,并设置值启动程序(其中正则表达式的起始位置r
发生)和长度(匹配子字符串/正则表达式的字符长度)。
注意:我曾经$NF+1
强制 awk 进行字符串到整数的转换,如下所示我知道数字位于 $NF 的起始位置(虽然你可以起诉substr($NF,1, RLENGTH)+1
也),然后从substr($NF, RLENGTH+1)
。
注意:更改 , 中的正则表达式match($NF, /^[+-]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?/)
以匹配几乎所有类型的数字(您可能也想使用正确的打印控件,请参阅正交频域调制)
答案2
您可以使用match
函数 ingawk
将组捕获到数组中并打印出每个元素,同时递增捕获的数字:
echo 'barbaz?cache_version=3fooooo' | gawk 'match($0, /(.*cache_version=)([[:digit:]]+)(foo.*)/, a) {print a[1] a[2]+1 a[3]}'