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

时间:2015-12-29 07:15:43

标签: 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.";

由于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;

上面的代码与sed的代码相同,但如何将modified content(“postgresql-9.4.service”)放入文件中,或打印出来?

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

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

3 个答案:

答案 0 :(得分:7)

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

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

替换完成后,返回代码将为1

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

来自Perl documentation

  

尽可能晚地执行 END代码块,即在perl之后   已经完成了程序的运行,而就在解释器之前   退出,即使它是由于die()函数退出。   (但如果它通过exec变形为另一个程序,或者不是   通过信号吹出水面 - 你必须自己陷阱(如果   你可以)。)你可能在文件中有多个END块 - 他们会   以与定义相反的顺序执行;那就是:后进先出   (LIFO)。使用-c运行perl时不执行END块   切换,或编译失败。

s operator

返回的替换次数
  

s/PATTERN/REPLACEMENT/msixpodualngcer

     

在字符串中搜索模式,如果找到,则替换该模式   用替换文本并返回替换次数   制成。

答案 1 :(得分:2)

在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

答案 2 :(得分:0)

如果只打印替换行,则可以直接检查输出:

if [[ -z $(sed -n 's/mariadb\(\.service\)/postgresql-9.4\1/p' something.conf) ]]; then
    echo nope
fi