I want to extract the Nth line after a matching pattern using grep
, awk
or sed
.
For example I have this piece of text:
Printing the lnb
th line after first blank/empty line:
Index of line to print (in bash shell):
lnb=2
Using sed
:
sed -ne '/^\s*$/{:a;n;0~'"$lnb"'!ba;p;q}' my_file`
Using perl
:
perl -ne '/^\s+$/ && $k++;$k!=0 && $k++ && $k=='"$lnb"'+2 && (print,last)' my_file`
Printing the lnb
th line after regular-expression match:
Using sed
:
sed -ne '/regex/{:a;n;0~'"$lnb"'!ba;p;q}' my_file
Using perl
:
perl -ne '/regex/ && $k++;$k!=0 && $k++ && $k=='"$lnb"'+2 && (print,last)' my_file
Bonus 1, Windows PowerShell (install Perl first) :
$lnb=2
perl -ne "/regex/ && `$k++;`$k!=0 && `$k++ && `$k==$lnb+2 && (print,last)" my_file
Bonus 2, Windows DOS command line :
set lnb=2
perl -ne "/regex/ && $k++;$k!=0 && $k++ && $k==%lnb%+2 && (print,last)" my_file
Printing ALL lnb
th lines after regular-expression match:
Using perl
(bash example):
perl -ne '/regex/ && $k++;$k!=0 && $k++ && $k=='"$lnb"'+2 && (print,$k=0)' my_file
To extract the Nth line after a matching pattern
you want:
awk 'c&&!--c;/pattern/{c=N}' file
e.g.
awk 'c&&!--c;/Revision:/{c=5}' file
would print the 5th line after the text "Revision:"/.
FYI the following idioms describe how to select a range of records given a specific pattern to match:
a) Print all records from some pattern:
awk '/pattern/{f=1}f' file
b) Print all records after some pattern:
awk 'f;/pattern/{f=1}' file
c) Print the Nth record after some pattern:
awk 'c&&!--c;/pattern/{c=N}' file
d) Print every record except the Nth record after some pattern:
awk 'c&&!--c{next}/pattern/{c=N}1' file
e) Print the N records after some pattern:
awk 'c&&c--;/pattern/{c=N}' file
f) Print every record except the N records after some pattern:
awk 'c&&c--{next}/pattern/{c=N}1' file
g) Print the N records from some pattern:
awk '/pattern/{c=N}c&&c--' file
I changed the variable name from "f" for "found" to "c" for "count" where appropriate as that's more expressive of what the variable actually IS.
I like solutions I can learn to redo, without having to google for it every time. This solution is not perfect, but uses simple grep commands that I can write from memory.
grep -A7 "searchpattern" file | grep -B1 "^--$" | grep -v "^--$"
You can change the 7 to the nth line you want after the search pattern. It then searches for the "group separator" --
and shows the last line before that. Then remove the group separators.
The only case this does not work correctly is if your data contains lines with only "--".