使用perl进行条件替换

xpt*_*xpt 3 sed perl

非常简单的假设问题,

我已达到 的限制sed,需要将sed脚本更改为perl. 所以对于sed有条件的替换

sed '/condition/ s/xx/yy/'
Run Code Online (Sandbox Code Playgroud)

如何在 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
Run Code Online (Sandbox Code Playgroud)

meu*_*euh 6

问题是,$1等等在每个新的正则表达式上都会重置,因此除非您在命令中重复它们,否则它们将为空s,即

s/^([135])(.)$/$1.$2-/ if /^([135])(.)$/'
Run Code Online (Sandbox Code Playgroud)

可以通过删除来简化if

s/^([135])(.)$/$1.$2-/
Run Code Online (Sandbox Code Playgroud)

在更一般的情况下,您可以保留捕获的值:

if (/^([135])(.)$/) { $a=$1; $b=$2; s/$&/$a.$b-/; }
Run Code Online (Sandbox Code Playgroud)


Kus*_*nda 6

如果您的目标是减少打字并增加如何在 Perl 和sed. 在这种情况下,Perlsed和 Perl 都允许通过指定空表达式来重用最近匹配的正则表达式。

sed '/^\([135]\)\(.\)$/ s//\1.\2-/'
Run Code Online (Sandbox Code Playgroud)
perl -pe '/^([135])(.)$/ && s//$1.$2-/'
Run Code Online (Sandbox Code Playgroud)

命令中的空正则表达式s///将重用前面测试中的表达式(通常是最近的匹配表达式)。

在 Perl 中,我们必须&&在测试和替换之间添加,以使其充当短路if语句。在 中sed,第一个表达式仅充当替换命令的地址。

一般来说,

sed '/condition/ s/xx/yy/'
Run Code Online (Sandbox Code Playgroud)

...将“相同”(考虑到稍微不同的语法和正则表达式风格)

perl -pe '/condition/ && s/xx/yy/'
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,直接应用替换会更简单:

sed 's/^\([135]\)\(.\)$/\1.\2-/'
Run Code Online (Sandbox Code Playgroud)
perl -pe 's/^([135])(.)$/$1.$2-/'
Run Code Online (Sandbox Code Playgroud)