我正在尝试编写一种非常简单的衬纸来查找以下情况:
foo N
并用
替换foo N-Y
例如,如果我有3个文件,并且其中有以下几行:
foo 5
foo 3
foo 9
以Y = 4运行脚本后,这些行将显示为:
foo 1
foo -1
foo 5
我偶然发现了一个现有线程,该线程建议在替代命令的replace一半中使用/ e运行代码,并且能够有效地从所有匹配项中减去Y,但是我不知道如何最好地打印出“ foo”因为当我尝试将foo和数字分成两个捕获组并重新打印出来时,perl认为我正在尝试将它们相乘并需要一个运算符。
我在这里:
find . -iname "*somematch*" -exec perl -pi -e 's/(Foo *)(\d+)/$1$2-4/e' {} \;
这当然是行不通的,“ Scalar找到了运算符在-e第1行中期望的位置,在“ $ 1 $ 2附近”。我对于如何最好地进行而不写更长的时间感到困惑。
编辑:更具体地说,如果启用了/ e选项以能够在替换中执行数学运算,是否有一种简单的方法可以将字符串打印到另一个捕获组中?没有尝试对它进行数学运算的替代?
或者,是否有一种简单的方法可以仅对部分图案进行手术替换?我试图结合使用m //和s ///来获得结果,但最终无济于事。
答案 0 :(得分:1)
替换部分在/e
下被视为 code ,因此需要使用合法的语法编写,就像您在程序中使用的一样。编写$t$v
不是合法语法(正则表达式中的$1$2
)。
连接字符串的一种方法是$t . $v
。然后,您还需要在加法前后加上括号,因为优先顺序规则将字符串$1
和$2
串联在一起,并再次尝试使用字母数字字符串,从而产生警告。所以
perl -i -pe's/(Foo *)([0-9]+)/$1.($2-4)/e'
我用\d
替换了[0-9]
,因为\d
匹配了Unicode中的所有“数字”,这似乎并不是您所需要的。
如果数学跟在模式的其余部分之后,还有另一种方法,就像您的示例中一样
perl -i -pe's/Foo *\K([0-9]+)/$1-4/e'
此处\K
是positive lookbehind的一种形式,它删除了该锚之前的所有匹配项,因此不会消耗它们。因此,根据需要仅替换[0-9]+
。