'sed: Replacing a range of text with contents of a file

There are many examples here and elsewhere on the interwebs for using sed's 'r' to replace a pattern, but it does not seem to work on a range, but maybe I'm just not holding it right.

The following works as expected, deleting BEGIN PATTERN and replacing it with the contents of /tmp/somefile.

sed -n "/BEGIN PATTERN/{ r /tmp/somefile d }" TARGET_FILE

This, however, only replaces END_PATTERN with the contents of /tmp/somefile.

 sed -n "/BEGIN PATTERN/,/END PATTERN/ { r /tmp/somefile d }" TARGET_FILE

I suppose I could try perl or awk to do this as well, but it seems like sed should be able to do this.



Solution 1:[1]

I believe that this does what you want:

sed  $'/BEGIN PATTERN/r somefile\n /BEGIN PATTERN/,/END PATTERN/d' file

Or:

sed  -e '/BEGIN PATTERN/r somefile' -e '/BEGIN PATTERN/,/END PATTERN/d' file

How it works

  • /BEGIN PATTERN/r somefile

    Whenever BEGIN PATTERN is found, this inserts the contents of somefile.

  • /BEGIN PATTERN/,/END PATTERN/d

    Whenever we are in the range from a line with /BEGIN PATTERN/ to a line with /END PATTERN/, we delete (d) the contains of the pattern buffer.

Example

Let's consider these two test files:

$ cat file
prelude
BEGIN PATTERN
middle
END PATTERN
afterthought

and:

$ cat somefile
This is
New.

Our command produces:

$ sed  $'/BEGIN PATTERN/r somefile\n /BEGIN PATTERN/,/END PATTERN/d' file
prelude
This is
New.
afterthought

Solution 2:[2]

This might work for you (GNU sed):

sed -e '/BEGIN PATTERN/,/END PATTERN/{/END PATTERN/!d;r somefile' -e 'd}' file

Solution 3:[3]

John1024's answer works if BEGIN PATTERN and END PATTERN are different. If this is not the case, the following works:

sed $'/PATTERN/,/PATTERN/d; 1,/PATTERN/ { /PATTERN/r somefile\n }' file

By preserving the pattern:

sed $'/PATTERN/,/PATTERN/ { /PATTERN/!d; }; 1,/PATTERN/ { /PATTERN/r somefile\n }' file

This solution can yield false positives if the pattern is not paired as potong pointed out.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 potong
Solution 3 Burak Gök