Search code examples
perlsedlines

Deleting lines matching regex along with 2 previous lines


I have a file where I need to remove the 2 lines before the regex foo.

bad 1
foo
good 1
good 2
good 3
bad 2
bad 3
foo
good 4
good 5
good 6
bad 4
bad 5
foo
good 7
bad 6
bad 7
foo
good 8
good 9
good 10
bad 8
bad 9
foo
good11

I can do it easily with sed :

casper_mint@casper-mint-dell /tmp $ cat dddd | sed '/bad/ , /foo/d'
good 1
good 2
good 3
good 4
good 5
good 6
good 7
good 8
good 9
good 10
good11

How can I do this in perl?


Solution

  • In a one liner:

    print -ne 'push @b, $_; @b = () if /^foo$/; print shift @b if @b > 2; END {print @b};' file
    

    Or demonstrated in a full script:

    use strict;
    use warnings;
    
    my @b;
    
    while (<DATA>) {
        push @b, $_;
        @b = () if /^foo/;
        print shift @b if @b > 2;
    }
    
    END {print @b};
    
    __DATA__
    bad 1
    foo
    good 1
    good 2
    good 3
    bad 2
    bad 3
    foo
    good 4
    good 5
    good 6
    bad 4
    bad 5
    foo
    good 7
    bad 6
    bad 7
    foo
    good 8
    good 9
    good 10
    bad 8
    bad 9
    foo
    good11
    

    Both Output:

    good 1
    good 2
    good 3
    good 4
    good 5
    good 6
    good 7
    good 8
    good 9
    good 10
    good11