Search code examples
regexperlmultiline

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?


Solution

  • 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?