Print line X lines before/after found line
Solution 1:
grep
will do this for you, with options -A
(after) and -B
(before), and -C
(context). An example I often use is:
sudo lspci -vnn | grep -i net -A 12
because this command will show 12 lines after the match, which includes the driver used to control the network (-i net) card. In general, the command is:
grep text_to_search -A n -B m file.extension
which will output m
lines before the match, and n
lines after the match. Or you can use
grep text_to_search -C n file.extension
to show a total of n
lines surrounding the text found (half before, half after the match).
Solution 2:
After looking into this question a little bit I think I have to revise my comment about the feasability using standard GNU tools without scripting. This may be very hard to do because of the special cases.
If you don't mind using awk I could offer the following solution. This script context.awk
ist still rather concise:
{
lines[NR] = $0
if (dump[NR]) {
print $0;
if ($0 ~ Pattern) {
if (NR-Delta in lines) {
print "---"
print lines[NR-Delta]
}
dump[NR+Delta] = 1
print $0;
}
if (NR-Delta in lines)
delete lines [NR-Delta];
}
It has to be called as follows:
awk -v Delta=X -v Pattern=PATTERN -f context.awk sample.txt
where X
is the desired "context distance" and PATTERN
the search pattern. The script tries to seperate multiple pattern contexts in the file by printing lines with ---
in between. So, for example, the following sample.txt
line1
line2
line3 XXX
line4
line5
line6
line7 XXX
line8
line9
line10 XXX
line11
using this call
awk -v Delta=3 -v Pattern=XXX -f context.awk sample.txt
will yield the followng output
line3 XXX
line6
---
line4
line7 XXX
line10 XXX
---
line7 XXX
line10 XXX