/two/{ :loop N /\(\(.*\n\)\{5\}\).*/{ s//\1Modified/ b } b loop }
Save that in x.sed and execute it as
sed -f x.sed file
or use the one-liner for GNU Sed:
sed '/two/{:a;N;/\(\(.*\n\)\{5\}\).*/{s//\1Modified/;b;};ba;}' file
Line by line analysis:
- 1-2: When the match is found, start a loop. In this loop,
- 3: Add a line to pattern space with the
N command. - 4: If there are 5 newline characters — the basic regex is
\(.*\n\)\{5\} —, put that in a capture group, leave the last line (.*) uncaptured and - 5: Substitute the whole pattern space* with the capture group followed by the
Modified line. - 6: Break the loop.
- 8: Else
loop again.
*An empty regex slot is equivalent to the previously used regex, so that 5th line is equivalent to s/\(\(.*\n\)\{5\}\).*/\1Modified/.
Less esoteric is to use Awk:
awk '{c--};/two/{c=5};c==0{$0="Modified"};{print}' file
That starts by decrementing a counter, and because, as all variables, c is initially zero, it only becomes positive if a match is found.
An even more explicit approach would be
awk 'BEGIN{c=-1};/two/{c=5};c==0{$0="Modified"};{print};c>=0{c=c-1}' file
Useful Sed resources:
endcould be replaced with$, so for exampleseq 10|sed '/2/,${/2/,+5{/2/,+4!s/.*/replaceString/}}'from accepted answer orseq 10| sed '/2/{:a;N;$!ba;s/[^\n]*/replaceString/6}'from the second answer. no such big difference, but easy adjustable if one could understood how they works. BTW, I retracted my close vote.t. Different answers you have will give you the same output fortwobut different output fort. It would also be good if you showed if you want a regexp or string match.MODIFIEDit werefifty-two? Should THAT line then match withtwoand so you'd change the 5th line after THAT and every 5th line from then on?