Multi-line replace

I would use ex for that kind of task, unless you really do have a stream of data. I'd keep the ex commands in a here document:

ex $FILENAME << END_EX_COMMANDS
" Find the mark, assuming it's an entire line
/^MARKER$/
" Delete the marker line
d
" Add the complex, multi-line text
a
Complex, vividly formatted text here.
Even more "specially" formatted text.
.
" The '.' terminates the a-command. Write out changed file.
w!
q
END_EX_COMMANDS

Using ex is an advantage to vi or vim users: they already know the keystrokes for the commands, although it gives you the sensation of editing blind. You can also do multiple adds or global substitutions, anything that vim can do in ':' mode.


If you have the text to be inserted at the marker(s) in a file named /tmp/insert.txt you can accomplish this task as follow:

sed '/MARKER/ r /tmp/insert.txt' < inputfile

The above sed command will read "inputfile" and look for MARKER. When it finds it, it inserts the contents of /tmp/insert.txt into the output stream.

If you want the marker itself to be deleted, try this:

sed '/MARKER/ {s/MARKER//; r /tmp/insert.txt
}' <inputfile

Note the "}" closing brace must be preceded by a new line.

As in the first command, the sed will operate on lines with the MARKER. It will substitute MARKER with nothing, and then it will read in /tmp/insert.txt


I believe this command is what you are looking for:

r FILENAME
     As a GNU extension, this command accepts two addresses.

     Queue the contents of FILENAME to be read and inserted into the
     output stream at the end of the current cycle, or when the next
     input line is read.  Note that if FILENAME cannot be read, it is
     treated as if it were an empty file, without any error indication.

     As a GNU `sed' extension, the special value `/dev/stdin' is
     supported for the file name, which reads the contents of the
     standard input.

Tags:

Sed