非常简单的假设问题,
我已经达到限制sed
并且需要将我的sed
脚本更改为perl
. 所以对于sed
有条件的替换
sed '/condition/ s/xx/yy/'
如何在 perl 中做到这一点?
例如,如何在 perl 中执行以下操作?
seq 6 > /tmp/tf
$ paste -d '' /tmp/tf /tmp/tf | sed -E '/[135]/s/^(.)(.)$/\1.\2-/'
1.1-
22
3.3-
44
5.5-
66
$ paste -d '' /tmp/tf /tmp/tf | perl -pe 's/$&/$1.$2-/ if /^([135])(.)$/'
.-
22
.-
44
.-
66
问题是
$1
在每个新的正则表达式上都会重置等等,所以除非你在s
命令中重复它们,否则它们将是空的,即这可以通过删除来简化
if
:在更一般的情况下,您可以保留捕获的值:
如果您的目标是减少打字并增加如何在 Perl 和
sed
. 在这种情况下,sed
Perl 和 Perl 都允许通过指定一个空表达式来重用最近匹配的正则表达式。命令中的空正则表达式
s///
将重用前面测试中的表达式(通常是最近匹配的表达式)。在 Perl 中,我们必须
&&
在测试和替换之间添加,让它充当短路if
语句。在sed
中,第一个表达式只是充当替换命令的地址。一般来说,
...将是“相同的”(考虑到稍微不同的语法和正则表达式风格)
但是,在这种情况下,直接应用替换会更简单:
使用Raku(以前称为 Perl_6)
或者
发布此内容是希望它对涉足 Raku 的 Perl 用户有用。在 Raku 中,捕获从 开始,并且使用...标记
$0
创建字符类(仅方括号保留用于分组)。此外,匹配通常对空白不敏感(即 Perl5是默认设置)。<[
]>
\x
尝试@Kusalananda 的第一个 Perl5 代码示例(如所述的带有 Raku 'accent')将产生 Raku 错误
Null regex not allowed
。因此,上面的第一个 Raku 答案看起来更像@Kusalananda 的最后一个Perl5 代码示例。(上面的第二个 Raku 答案使用了if
条件,一些用户可能会发现它更具可读性)。样本输入:
样本输出:
附录:由于 OP 发布了连接相同数字的示例数据——我想知道这里是否还有关于backreferences的未回答问题。在 Raku 中,如果您想在匹配中重用第一个捕获(例如运算符的左侧
s///
),请执行以下操作:或者
或(命名捕获,如下):
或者
上面的第二个和第四个例子使用了 Raku 新的“替代赋值”表示法,它(为了提高可读性)还允许使用各种分隔符——括号、花括号等。(当然,
if
可以使用前面提到的单独的条件部分,但这可能会导致代码可读性降低)。https://raku.org/archive/rfc/144.html
https://raku.org/archive/rfc/331.html
https://raku.org