In sed, I’d like to replace a multi-line block of text after a match, for example, after matching “foo”, supposing its line number is 0. I want to replace the text block from line -3 to line +5, i.e. the text bock between the third line proceeding the matching line and the fifth line after the matching line, by another text block bar1\nbar2. I’d like to be able to do this in two scenarios:
1) Keep the matching line after the replaced block;
2) remove the matching line together with those lines -3 and +5.
Please help me.
Thank you.
This might work (GNU sed):
Explanation:
The commands fall into two halves:
match5 further lines are appended.The details are as follows:
:ais a loop placeholder$qon end-of-file print all lines within the pattern space (PS).Nappend the next line to the PSs/\n/&/3replace the 3rd newline character by itself. This a counting device for checking that 3 lines are in the PS.Taif the previous substitution failed loop to the loop placeholdera/match/!{P;D}look thematchand if it fails print upto the first newline and then delete that line and it’s newline (this invokes a new cycle).:bis a loop placeholder N.B. a match has been found at this point.$bcif end-of-file branch forward to the placeholdercNappend the next line to the PSs/\n/&/8replace the 8th (3 before 5 after) newline character by itself. This a counting device for checking that 5 lines are appended to the PSTbif the previous substitution failed loop to the loop placeholderb:cis a loop placeholders/.*/bar1\nbar2/replace the PS with the required string.The second one liner makes a copy of the
matchline and appends it to the substituted string.Alternative solutions: