Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

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

by johngg (Canon)
on Nov 02, 2020 at 13:11 UTC ( [id://11123342]=note: print w/replies, xml ) Need Help??


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.

I slurp the data into a string then use regexen and @- & @+ to find the point just after the start marker and just before the end marker. I then use substr and join to replace the necessary text between the markers, working backwards from the right side of the string by sorting start marker position into descending order, greping away any incomplete marker events. ( Note that I have formed the habit of opening file handles against HEREDOCs rather than using the __DATA__ section as it allows me to use multiple data sources in scripts as necessary. )

use strict; use warnings; open my $inFH, q{<}, \ <<__EOD__ or die qq{open: < HEREDOC:$!\n}; aaa AAAAAA ccc ddd BBBBBB EEEEEE zzz xxx yyy FFFFFF 111 GGGGGG 222 333 CCCCCC 444 555 666 DDDDDD 777 888 999 __EOD__ my $inText = do { local $/; <$inFH>; }; close $inFH or die qq{close: < HEREDOC:$!\n}; my @events = ( { start => qr{(?x) GGGGGG $/ }, stop => qr{(?x) HHHHHH $/ }, repl => [ qw{ f31 f32 f33 f34 } ], }, { start => qr{(?x) AAAAAA $/ }, stop => qr{(?x) BBBBBB $/ }, repl => [ qw{ f11 f12 f13 } ], }, { start => qr{(?x) EEEEEE $/ }, stop => qr{(?x) FFFFFF $/ }, repl => [ qw{ f31 f32 f33 f34 } ], }, { start => qr{(?x) CCCCCC $/ }, stop => qr{(?x) DDDDDD $/ }, repl => [ qw{ f21 f22 } ], }, ); foreach my $rhEvent ( @events ) { $rhEvent->{ startPos } = $inText =~ $rhEvent->{ start } ? $+[ 0 ] : -1; $rhEvent->{ stopPos } = $inText =~ $rhEvent->{ stop } ? $-[ 0 ] : -1; } substr $inText, $_->{ startPos }, $_->{ stopPos } - $_->{ startPos }, join $/, q{}, @{ $_->{ repl } }, q{} for sort { $b->{ startPos } <=> $a->{ startPos } } grep { $_->{ startPos } >= 0 && $_->{ stopPos } >= 0 } @events; print $inText;

The output.

aaa AAAAAA f11 f12 f13 BBBBBB EEEEEE f31 f32 f33 f34 FFFFFF 111 GGGGGG 222 333 CCCCCC f21 f22 DDDDDD 777 888 999

I hope this is of interest.

Update: Corrected grep link.

Cheers,

JohnGG

  • 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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11123342]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-20 01:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found