Description
In the following examples, we want to enclose each of the first 5 matches of [0-9]+ with a pair of brackets, i.e., N=5 for this case.
Raw Input Desired Output
first 1111
no numbers
second 222
third 333 fourth 44444
no numbers
fifth 5555 sixth 666666
number 7777
number 88888
no numbers
first [1111]
no numbers
second [222]
third [333] fourth [44444]
no numbers
fifth [5555] sixth 666666
number 7777
number 88888
no numbers
Script and Comments
Script1
[ 1] /[0-9]/!b
[ 2] :loop0
[ 3] /([0-9]+([^0-9]+|$)){5}/!{
[ 4] $!N
[ 5] $!b loop0
[ 6] }
[ 7] s/([0-9]+([^0-9]+|$)){1,5}/&\n/
[ 8] h
[ 9] s/\n[^\n]*$//
[10] s/[0-9]+/[&]/g
[11] x
[12] s/^.*\n//
[13] G
[14] s/^([^\n]*)\n(.*)/\2\1/
[15] :loop1
[16] n
[17] b loop1
Comments -r
  1. There may be some other matches other than the first N ones in the same line as the first N-th match. For example, in the sample data, 6666 has to be replaced while 55555 does not.
  2. When the line containing the first match is found, the script appends the next lines to PS until all the first N matches are have been read into PS. This is done via Steps [2] thru [6].
    GNU sed 4.2.1 does not interpret {5} in RE of Step [3] correctly, you have to expand it by yourself via writing [0-9]+([^0-9]+|$) 5 times and concatenate them together, like
    [0-9]+([^0-9]+|$)[0-9]+([^0-9]+|$)[0-9]+([^0-9]+|$)[0-9]+([^0-9]+|$)[0-9]+([^0-9]+|$).
  3. There may be some matches other than the first N ones in PS; moreover, they are in the last line of PS. To modify only the first N matches:
    • First divide PS into two parts such that the first part contains all the first N matches without any other one. (Step [7])
    • Save the contents of PS to HS for further reference. (Step [8])
    • Remove the second part from PS. (Step [9])
    • Perform replacements on all the N matches. (Step [10])
    • Exchange the contents of PS and HS. (Step [11])
    • Now, PS contains the original first part, followed by a newline, then the original second part. Step [12] removes the first part and the delimiting newline.
    • Step [13] appends the modified first part to PS. A newline character is used to delimit these two parts.
    • Step [14] exchanges these two parts and removes that delimiting newline.
  4. For lines after the one containing the N match, Steps [15] thru [17] will read and print them, one line at a time.