非常简单的假设问题,
我已达到 的限制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)
问题是,$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)
如果您的目标是减少打字并增加如何在 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)