perl 多行查找和替换为正则表达式

perl Multiline Find and Replace with regex

我有一个属性文件 test.properties,其中包含如下所示的一些内容:

#DEV
#jms_value=devdata.example
#TST
#jms_value=tstdata.example
#DEV
#ems_value=emsdev.example

我想根据文件所在的环境取消注释环境名称下的行。

如果文件进入DEV环境。我需要取消注释所有“#DEV”下的行。我使用了以下命令:

perl -i -p -e 's/#DEV\n#(.*)/#DEV\n/g;' test.properties

这不会更改文件中的任何内容。

谁能帮我找到解决方案?

您可以尝试这样的操作:

perl -pe'if ($a==1) {s/^#//;$a=0;} $a=1 if (/^#DEV/)'

只需使用一个变量作为标志。如果您看到 #DEV,将其设置为 1,否则将其设置为 0。如果设置了标志,请删除前导 # - 但在设置之前检查标志!

perl -pe 's/^#// if $delete; $delete = /^#DEV$/;' input-file

一种方法是吞噬整个文件,来自 perlrun doc

The special value 00 will cause Perl to slurp files in paragraph mode. Any value 0400 or above will cause Perl to slurp files whole, but by convention the value 0777 is the one normally used for this purpose.

我稍微修改了示例输入以供演示:

$ cat ip.txt 
#DEV
#jms_value=devdata.example
#TST
#jms_value=tstdata.example
#DEV
#ems_value=emsdev.example
xyz #DEV
#abc

向 OP 的正则表达式添加 -0777 选项

$ perl -0777 -pe 's/#DEV\n#(.*)/#DEV\n/g' ip.txt 
#DEV
jms_value=devdata.example
#TST
#jms_value=tstdata.example
#DEV
ems_value=emsdev.example
xyz #DEV
abc

如果 #DEV 必须只在行首匹配,使用 m 标志

$ perl -0777 -pe 's/^#DEV\n#(.*)/#DEV\n/mg' ip.txt 
#DEV
jms_value=devdata.example
#TST
#jms_value=tstdata.example
#DEV
ems_value=emsdev.example
xyz #DEV
#abc


也可以使用正后视:

$ perl -0777 -pe 's/^#DEV\n\K#//mg' ip.txt 
#DEV
jms_value=devdata.example
#TST
#jms_value=tstdata.example
#DEV
ems_value=emsdev.example
xyz #DEV
#abc


另请注意: What is the difference between and in a Perl regex?