Swarna Gowri Swarna Gowri - 11 days ago 7
Perl Question

perl regex multiline

I am trying to write a perl script that replaces a few lines of text with a few other lines, I am a perl newbie, appreciate any help.

Need to replace

'ENTITLEMENT_EVS_V',
NULL,
NULL,


with:

'ENTITLEMENT_EVS_V',
ENTITLEMENT_CATEGORY_CODE,
6,


I am unable to do so, especially the regex part. I tried many things, but the script currently stands at:

#!/usr/bin/env perl
my ($lopen_fh, $lwrite_fh);

# my $l_reg_evs = qq{
#'ENTITLEMENT_EVS_V',
#NULL,
#NULL,
#};
my $l_reg_evs = qr/(\'ENTITLEMENT_EVS_V\',
NULL,
NULL,
)/;


my $l_evs=qq{
'ENTITLEMENT_EVS_V',
ENTITLEMENT_CATEGORY_CODE,
6,
};

open ($lopen_fh, '<', "/home/cbdev2/imp/dev/src/deli/entfreeunits/config/entfreeunits/stubs/DirectVariables_evEntlCategory.exp") or die $!;
open ($lwrite_fh, '>', "/home/cbdev2/imp/dev/src/deli/entfreeunits/config/entfreeunits/stubs/DirectVariables_evEntlCategory.new.exp") or die $!;

while(<$lopen_fh>) {
$_ =~ s/$l_reg_evs/$l_evs/m;
print $lwrite_fh $_;
}

close $lopen_fh;
close $lwrite_fh;

Answer

I think I'd write something like this. It expects the path to the input file as a parameter on the command line and prints the result to STDOUT

It requires all of the following to be true

  • The first line of the block to search for and the block to be replaced are always identical

  • The number of lines in the block to search for and the block to be replaced are always the same

  • The input file always contains the first line of the block to search for exactly once

  • There is no need to check that the lines in the file after the first one in the block are NULL,, and it is sufficient to locate just the first line and remove the following lines whatever they contain

It works by reading the input file and copying it to STDOUT. If it encounters a line that contains the first line of the replacement block, then it reads and it discards lines until the number of lines read is equal to the size of the replacement block. Then the text in the replacement block is printed to STDOUT and the copying continues

use strict;
use warnings 'all';
no warnings 'qw';  # avoid warning about commas in qw//

my @replacement = qw/
    'ENTITLEMENT_EVS_V',
    ENTITLEMENT_CATEGORY_CODE,
    6,
/;

open my $fh, '<', $ARGV[0];

while ( <$fh> ) {
    if ( /$replacement[0]/ ) {
        <$fh> for 1 .. $#replacement;
        print "$_\n" for @replacement;
    }
    else {
        print;
    }
}

This works fine with some sample data that I created, but I have no way of knowing whether the stipulations listed above apply to your actual data. I'm sure you will let me know if something needs adjusting

Comments