egrep -B4 /foo/ file
####
# put the line into the cache/queue; shorten the array if it's more than we want; print the array if current line mataches.
perl -ne 'push @lines, $_; shift @lines if scalar(@lines)>4; print join "", @lines if /foo/' file
# if you don't want the current line printed as one of the 4, just rearrange a little:
perl -ne 'print join "", @lines if /foo/; push @lines, $_; shift @lines if scalar(@lines)>4' file
##
##
use Tie::File;
use Fcntl 'O_RDONLY';
my @array;
tie @array, 'Tie::File', $ARGV[0], mode => O_RDONLY or die;
foreach my $i ( 0 .. $#array ){
# no, doesn't handle index edge case of $i < 4
print join "", @array[$i-4,$i-1] if $array[$i] =~ /foo/;
}