vick_codr
vick_codr

Reputation: 23

perl Multiline Find and Replace with regex

I have a properties file test.properties with some content like shown:

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

I want to uncomment the line under the environment name based on the environment where the file goes.

If the file goes to DEV environment. I need the line under the all '#DEV' need to be uncommented. I have used the following command:

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

This is not changing anything in the file.

Can anyone help me in finding a solution for this?

Upvotes: 2

Views: 553

Answers (3)

Sundeep
Sundeep

Reputation: 23667

One way is to slurp the entire file, from 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.

I have slightly modified sample input for demonstration:

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

Adding -0777 option to OP's regex

$ 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

If #DEV has to be matched at start of line only, use m flag

$ 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


Positive lookbehind can be used as well:

$ 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


Also note: What is the difference between \1 and $1 in a Perl regex?

Upvotes: 3

choroba
choroba

Reputation: 241748

Just use a variable as a flag. If you see #DEV, set it to 1, otherwise set it to 0. Remove the leading # if the flag is set - but check the flag before setting it!

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

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

You can try something like this:

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

Upvotes: 0

Related Questions