检查`perl -i -pe`是否进行了任何替换

Jus*_*Moh 5 regex bash perl sed

GNU sed,我可以显示成功替换搜索模式的结果.简单示例如下:

echo -e "nginx.service\nmariadb.service\nphp-fpm.service" > something.conf;
sed -ri 's|(mariadb)(\.service)|postgresql-9.4\2|w sed-output.log' something.conf;
[[ -s sed-output.log ]] && echo "Pattern found and modified. $(cat sed-output.log)" || echo "Pattern not found.";
Run Code Online (Sandbox Code Playgroud)

因为sed在处理多线时有限制,我切换到了perl.

echo -e "nginx.service\nmariadb.service\nphp-fpm.service" > something.conf;
perl -i -pe 's|(mariadb)(\.service)|postgresql-9.4\2|' something.conf;
Run Code Online (Sandbox Code Playgroud)

上面的代码也是这样sed,但我如何将modified content(" postgresql-9.4.service")放入文件或打印出来?

基本上我想要实现的是,在脚本执行之后,它告诉我它是否成功(以及实际替换的是什么),如果没有,我将显示一条无法找到和替换的消息.


编辑:
突出显示我想得到(only-the-)modified content,这表明我的脚本成功了.因为perl -i -pe 's/pattern/replace/' file,我不知道它是返回真还是假.当然,我可以简单grep -E "/pettern/"地找出答案,但这不是问题.

Jua*_*doy 7

此代码将抛出一个等于替换完成0时的退出代码:

$ perl -i -pe '$M += s|(mariadb)(\.service)|postgresql-9.4\2|;END{exit 1 unless $M>0}' something.conf
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

没有替换时,返回代码将是1:

$ perl -i -pe '$M += s|(maria)(\.service)|postgresql-9.4\2|;END{exit 1 unless $M>0}' something.conf
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

Perl 文档

一个END码块执行尽可能晚,即,perl的已经完成运行程序和之后要退出的解释之前,即使是离开作为模具()函数的结果.(但如果它通过exec变成另一个程序,或者被信号吹出水面则不会 - 你必须自己陷阱(如果可以的话).)你可能在文件中有多个END块 - 它们会以与定义相反的顺序执行; 那就是:后进先出(LIFO).使用-c开关运行perl时,或者编译失败时,不会执行END块.

运营商返回的替换数量s

s/PATTERN/REPLACEMENT/msixpodualngcer

在字符串中搜索模式,如果找到,则用替换文本替换该模式,并返回所做的替换次数.


Bor*_*din 3

它在 Perl 中没有那么整洁,因为您必须显式打开日志文件,并且对于必须位于块中的单行BEGIN。但 Perl 会s///返回所做更改的数量,因此您可以测试它的真实性

另请注意,这$2比 Perl 中的更好\2,因为后者表示代码点为 2 的字符,或 Unicode U+0002 START OF TEXT

perl -i -pe ' BEGIN { open F, ">perl-output.log" } print F $_ if s|(mariadb)(\.service)|postgresql-9.4$2| ' something.conf
Run Code Online (Sandbox Code Playgroud)