perl

Replace multiple occurrences of the word in the line of the file using Perl


Need to replace multiple occurrences of the words in the lines of the text file:

#!/usr/bin/perl

use strict;
use warnings;
use Tie::File;

my $string2 = 'first_part';
my $string3 = 'middle_part';
my $string4 = 'last_part';
my @contents=();

tie @contents, 'Tie::File','test.html' or die "Not able to Tie test.html\n";

my $count=1;
foreach (@contents)
{
    my $string = $_;
    my $quoted_substring = quotemeta($string);
    my $before = 'test_example_start';
    my $after  = 'text_example_end';
    if ($string =~ /\Q$before\E(.*?)\Q$after\E/) {
        my $finalstr = "$string2$1$string3$1$string4"; 
        s/$quoted_substring/$finalstr/g;
        print $finalstr;  
    } 

    $count++;
    my $finalstr ='';
}

untie @contents;

Actual string:

test_example_start this is lesson-1 text_example_end where everyone attended the class test_example_start this is lesson-2 text_example_end where two members attended the class test_example_start this is lesson-3 text_example_end where five members attended the class

expected result:

first_part this is lesson-1 middle_part this is lesson-1 last_part where everyone attended the class first_part this is lesson-2 middle_part this is lesson-1 last_part where two members attended the class first_part this is lesson-1 middle_part this is lesson-3 last_part where five members attended the class

current result: whole paragraph is replaced with only one line. as below

first_part this is lesson-1 middle_part this is lesson-1 last_part

Solution

  • Your question seems a bit confusing. The requirements are not very clear, despite the fact that you provided "actual string" and "expected result".

    This code should provide something very close to what you want:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    open FILE, "<", "test.html" or die $!;
    
    while (my $fileline = <FILE>) {
        while ($fileline =~ m/test_example_start(.*?)text_example_end(.*?)((?=test_example_start)|($))/gi) {
            print "first_part$1middle_part$1last_part$2";
        }
        print "\n";
    }
    
    close FILE;
    

    Assuming that the contents of the file test.html are the following:

    test_example_start this is lesson-1 text_example_end where everyone attended the class test_example_start this is lesson-2 text_example_end where two members attended the class test_example_start this is lesson-3 text_example_end where five members attended the class

    then, the above script's output will be:

    first_part this is lesson-1 middle_part this is lesson-1 last_part where everyone attended the class first_part this is lesson-2 middle_part this is lesson-2 last_partwhere two members attended the class first_part this is lesson-3 middle_part this is lesson-3 last_part where five members attended the class

    I'm not sure if this is what you want, because I don't know what exactly you want to be inserted in the newly created middle_part

    Aside from a correction in your regex, and the code cleanup, the key point here is that, if you want all of a line's ocurrences to be replaced, then you should put the line test inside a while block, not an if.