在数学旁边打印字符串会使用/ e修饰符进行s //替换

时间:2018-06-21 01:21:51

标签: perl

我正在尝试编写一种非常简单的衬纸来查找以下情况:

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 ///来获得结果,但最终无济于事。

1 个答案:

答案 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'

此处\Kpositive lookbehind的一种形式,它删除了该锚之前的所有匹配项,因此不会消耗它们。因此,根据需要仅替换[0-9]+