$ cat context.awk
BEGIN {
BEFORE=5;
AFTER=5;
MAX=10
C=-1;
}
function last(N)
{
if(N>L) return("");
return(LINE[(L-N)%MAX]);
}
(BEFORE >= MAX) { MAX=BEFORE+1 }
{ LINE[(++L)%MAX]=$0 } # Remember line for later
(C--) > 0 {
if($0 ~ PAT) C=AFTER;
print ; next
}
($0 ~ PAT) {
# Extra checking to avoid re-printing lines from 'after'
C += AFTER-1;
if((C < 0) && ((-C) <= AFTER)) C=-C;
else C=BEFORE;
for(N=C; N>=0; N--) print last(N);
C=AFTER;
}
$ cat input
c
d
e
f
pat
g
h
h
i
i
pat
j
k
l
m
n
o
p
$ awk -f context.awk PAT="pat" BEFORE=3 AFTER=2 input
d
e
f
pat
g
h
h
i
i
pat
j
k
$