You can do this fairly simply with sed
:
printf %s\\n 1 2 3 4match 5match 6 \
7match 8 9 10 11match |
sed -e'1N;$!N;/\n.*match/!P;D'
I don't know why anyone would say otherwise, but to find a line and print previous lines sed
incorporates the built-in P
rint primitive which writes only up to the first \n
ewline character in pattern space. The complementary D
elete primitive removes that same segment of pattern space before recursively recycling the script with what remains. And to round it off, there is a primitive for appending the N
ext input line to pattern space following an inserted \n
ewline character.
So that one line of sed
should be all you need. You just replace match
with whatever your regexp is and you're golden. That should be a very fast solution as well.
Note also that it will correctly count a match
immediately preceding another match
as both a trigger to quiet output for the previous two lines and quiet its print as well:
1
7match
8
11match
In order for it to work for an arbitrary number of lines, all you need to do is get a lead.
So:
printf %s\\n 1 2 3 4 5 6 7match \
8match 9match 10match \
11match 12 13 14 15 16 \
17 18 19 20match |
sed -e:b -e'$!{N;2,5bb' -e\} -e'/\n.*match/!P;D'
1
11match
12
13
14
20match
...deletes the 5 lines preceding any match.
awk '{l[m=NR]=$0}/banana/{for(i=NR-2;i<=NR;i++)delete l[i]}END{for(i=1;i<=m;i++)if(i in l)print l[i]}'
. This is not efficient, so this is just a hint, not a solution. – manatwork Jan 24 '12 at 16:38tac file | sed ... | tac
. :P – angus Jan 24 '12 at 16:54sed '/banana/,+2d' file
that will also work – Akaks Jan 06 '15 at 12:32awk 'tolower($0)~/bandana/{print prev[!idx];print prev[idx]} {idx=!idx;prev[idx]=$0}' filein
Since this is a comment and not an answer (there are already other answers), I won't go into too much detail, but the crux of it is you always have the previous two records in prev[0] and prev[1], the "freshest" depending on which iteration but always inprev[idx]
, so when you print, you print in!idx
thenidx
order. Regardless, alternateidx
and put the current record inprev[idx]
. – Luv2code Dec 17 '16 at 16:20I
do in'/banana/I,+2 d'
. Can anyone explain? – Iresh Dissanayaka Aug 22 '22 at 08:47