Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I spent ages trying to figure this out. As it happens, I don't need to do it any more; I found another way. But for the sake of my sanity, I'd like to know the answer anyway.

It's quite easy to use sed to replace a marker with some piece of text. What I can't figure out is how to make sed insert a huge block of text, with complex formatting such as multiple lines, tab characters, etc. How do you do that? Is sed the best thing to use or what?

share|improve this question
1  
I find that python & regex are much flexible than sed in complex multi-line substitutions. –  tombolinux Feb 26 '13 at 5:04

3 Answers 3

up vote 2 down vote accepted

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

share|improve this answer

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.

share|improve this answer

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.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.