Description
Get the N-th matched line.
In the following, we want to get the 5-th line containing 'match'.
Raw Input Desired Output
......
match-1
match-2...match-2....
.....
match-3...
.....
.....
match-4...
.....
match-5...
match-6...
match-5...
Script and Comments
Script1
[ 1] /match/!d
[ 2] H
[ 3] x
[ 4] /^(\n[^\n]*){5}/!{
[ 5] x
[ 6] d
[ 7] }
[ 8] s/^.*\n//
[ 9] q
Comments
  1. The `-r' option of GNU sed must be used to make it interpret REs as EREs; otherwise, you have to escape the parentheses and brackets in the script.
  2. The Pattern Space and the Hold Space are abbreviated to PS, and HS, respectively.
  3. The script use HS to keep matched lines.
  4. If the current line does not contain the desired string (`match' in this case), command `d' of Step [1] is used to skip it and starts a new cycle.
  5. Each time a matched line is found:
    • Step [2] appends it to HS.
    • Step [3] exchanges the contents of PS and HS.
    • If PS does not contain exactly N lines (N=5 in this case),
      Step [5] exchanges the contents of PS and HS, and
      Step [6] will start a new cycle.
    • Otherwise, Step [8] deletes first N-1 matched lines,
      Step [9] prints the desired line, then sed terminates.
Script2
[ 1] /match/!d
[ 2] H
[ 3] x
[ 4] s/^([^\n]*\n){5}//
[ 5] /\n/!q
[ 6] x
[ 7] d
Comments
  1. A neat version.