The challenge to turn this into a Perl one-liner proved too enticing.
I've assumed that the pattern can match more than one time in the file, but that if one of the lines deleted following the match contains the same pattern again, it gets ignored. This may or may not be an edge condition that you need to be aware of.
My approach builds a buffer of read lines. When the buffer reaches five lines long, the first line in gets shifted off the FIFO queue and printed. If the "match" line is detected, that line along with the buffer will be discarded. Then three more lines are read but ignored. Finally, upon completion of reading the file, whatever lines are still in the buffer get printed too.
The following is a long-hand version of my script first:
use strict; use warnings; my @buffer; my $re = qr/10/; while (<DATA>) { if ( $_ =~ $re ) { @buffer = (); my $count = 0; while( <DATA> and $count++ < 2 ){}; } else { push(@buffer, $_); if( defined( $buffer[5] ) ) { print shift(@buffer); } } } print @buffer; __DATA__ Line 01 Line 02 Line 03 Line 04 Line 05 Line 06 Line 07 Line 08 Line 09 Line 10 Line 11 Line 12 Line 13 Line 14 Line 15 Line 16 Line 17 Line 18 Line 19 Line 20
To convert this to a one-liner, we'll use the -n option, which implicitly creates the outer while(){} loop. The only problem with the -n option is that the remaining items in the buffer would get dropped if we didn't come up with a plan to deal with them after the implicit while() loop. The way to do this is to define an END{} block. The END{} block gets executed just after the while() loop completes, and just before the one-liner terminates execution. The -i.bak switch is used to specify in-place editing with the creation of a backup file. And as you see by looking at the code, we're hard-wiring the match value. Why not? One liners are disposable.
Here's how it looks:
perl -ni.bak -e "if(/10/){@buf=();$cnt=0;while(<> and $cnt++<2){}}else +{push @buf,$_;if(defined $buf[5]){print shift(@buf)}}END{print @buf}" + mytest.txt
Enjoy!
Dave
In reply to Re: Regex question
by davido
in thread Regex question
by jamsda
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |