in reply to The best way to replace several fragments of the file starting with the one pattern(marker) and ending with another pattern/marker.

Yet another way to do it. I believe Perl 5.10 is only needed because of the state variable. If it were moved above the loop and made into a my variable, an earlier Perl should work. I also moved the informational output to STDERR.

#!/usr/bin/env perl use 5.010; use strict; use warnings; my %marker = ( "AAAAAA\n" => { end => "BBBBBB\n", repl => <<'EOD', f11 f12 f13 EOD }, "CCCCCC\n" => { end => "DDDDDD\n", repl => <<'EOD', f21 f22 EOD }, ); while ( <DATA> ) { state $section; warn "$. $_"; if ( $section ) { if ( $_ eq $section->{end} ) { warn "========= End of the fragment detected at $.\n"; print $section->{repl}; $section = undef; } } elsif ( $section = $marker{$_} ) { warn "========= Start of the fragment detacted at $.\n"; } else { print; } } __DATA__ aaa aaa AAAAAA ccc ddd BBBBBB 111 222 333 CCCCCC 444 555 666 DDDDDD 777 888 999
  • Comment on Re: The best way to replace several fragments of the file starting with the one pattern(marker) and ending with another pattern/marker.
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: The best way to replace several fragments of the file starting with the one pattern(marker) and ending with another pattern/marker.
by likbez (Sexton) on Nov 01, 2020 at 16:15 UTC

    This looks like a solution based on ingenious emulation of Perl range operator with the advantage that it can accommodate multiple fragments.

    Like in Perl range operator there is a variable this is true within the range and false outside.

    Thank you !

    Here is a slightly modified variant that I used for testing:

    [0] # cat test_range2 #!/usr/bin/env perl use 5.010; use strict; use warnings; my $debug=0; my %marker = ( "AAAAAA\n" => { end => "BBBBBB\n", repl => <<'EOD', f11 f12 f13 EOD }, "CCCCCC\n" => { end => "DDDDDD\n", repl => <<'EOD', f21 f22 EOD }, ); state $section; while ( <DATA> ) { ($debug) && warn "$. $_"; if ( $section ) { if ( $_ eq $section->{end} ) { ($debug) && warn "========= End of the fragment detected a +t $.\n"; print $section->{repl}; $section = undef; print; } } elsif ( $section = $marker{$_} ) { ($debug) && warn "========= Start of the fragment detacted at +$.\n"; print; # print marker }else{ print; } } __DATA__ aaa aaa AAAAAA ccc ddd BBBBBB 111 222 333 CCCCCC 444 555 666 DDDDDD 777 888 999
    That produces:
    [0]  # perl  test_range2
    aaa
    aaa
    AAAAAA
    f11
    f12
    f13
    BBBBBB
    111
    222
    333
    CCCCCC
    f21
    f22
    DDDDDD
    777
    888
    999