2016-10-05 50 views
1

perl的多查找和使用正则表达式替换

我有一个属性文件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\1/g;' test.properties 

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

任何人都可以帮助我找到解决方案吗?

+2

默认perl的命令行读出的输入(一个文件或从管道)线通过线。有了这个条件,你显然不能使用多线模式。 –

回答

1

一种方式是啜整个文件,从perlrun doc

特殊值00将导致Perl的段落模式啜文件。 任何值0400或以上将导致Perl整个文件夹,但通过 约定值0777是通常用于此目的的文件。

示范

我稍微修改样本输入:

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

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

$ perl -0777 -pe 's/#DEV\n#(.*)/#DEV\n\1/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\1/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 \1 and $1 in a Perl regex?

0

你可以尝试这样的事情:

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

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

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

再请@choroba请描述您的答案解决的问题。你的努力只服务于OP,只有当你的分析是正确的。这不是Stack Overflow的工作方式。 – Borodin

+2

@Borodin:我的答案试图解决问题中提出的问题:如何取消注释给定环境名称的环境名称和以下行。 – choroba

+0

@Borodin:对不起,应该是“如何取消给定环境名称后的行注释”。 – choroba