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.