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] G
[ 3] s/(\n[^\n]*){5}$//
[ 4] /\n/!q
[ 5] x
[ 6] d
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.
    If it contains 3 matched lines, it looks like
    1st-matched \n 2nd-matched \n 3rd-matched \n
  4. If the current line is not matched, Step [1] is used to skip it and start a new cycle.
  5. Otherwise, we use the following steps to check whether the current line is the 5th-matched one:
    • first append the previously matched lines to PS via Step [2],
    • then try to perform a substitution by Step [3].
      If succeeds only when PS contains exactly 5 lines.
    • A successful substitution will trim off all lines except the 5-th matched lines. Step [4] will print it, then sed terminates.
    • Otherwise, PS contains all matched line till now. Step [5] moves them to HS, and Step [6] will start a new cycle.