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'm attempting to replace a pattern in a file with the complete contents of another file using sed.

Currently I am using:

sed "s/PATTERN/`cat replacement.txt`/g" "openfile.txt" > "output.txt"

However, if the replacement file contains any characters such as ', ", or / I start getting errors due to input not being sanitized.

I have been trying to use this guide to aid me, but I am finding it quite hard to follow. If I try the suggested r file command, I just end up with a string.

What is the best way to approach this?

share|improve this question

4 Answers 4

up vote 2 down vote accepted

This should work for you. I did not vote to close as duplicate since you had specified you have ', / and " characters in your file. So, I did the testing as below.

I have file1 contents as below.

cat file1
ramesh' has " and /
in this file
and trying
"to replace'
the contents in 
/other file.

Now, file2 is as below.

cat file2
This is file2
PATTERN 
After pattern contents go here. 

As per the shared link, I created the script.sed as below.

cat script.sed
/PATTERN/ {
  r file1
  d
}

Now, when I run the command as sed -f script.sed file2, I get the output as,

This is file2
ramesh' has " and /
in this file
and trying
"to replace'
the contents in 
/other file.
After pattern contents go here. 

EDIT: This works well with multiple patterns in the file as well.

share|improve this answer
    
This worked great. Thank you. What is the purpose of the delete command? –  Sam Aug 26 at 3:45
    
@Sam, do you mean the d at the end of script.sed file? I tried removing it and ran it and still got the same output. So, I am not sure what exactly it does. –  Ramesh Aug 26 at 3:49
    
@Ramesh: Without d, PATTERN remain in the file. –  cuonglm Aug 26 at 5:15
3  
Note that it doesn't replace PATTERN with the content of the file, but any full line containing PATTERN with the content of the file. –  Stéphane Chazelas Aug 26 at 5:52

If you need an awk solution, you could use something like below.

 awk '/PATTERN/{system("cat file1");next}1' file2

Testing

cat file1
ramesh' has " and /
in this file
and trying
"to replace'
the contents in 
/other file.

Now, I have file2 as below.

cat file2
This is file2
PATTERN 
After pattern contents go here.
PATTERN 

Now, I use the above mentioned awk command.

Output:

This is file2
ramesh' has " and /
in this file
and trying
"to replace'
the contents in 
/other file.
After pattern contents go here.
ramesh' has " and /
in this file
and trying
"to replace'
the contents in 
/other file.

References

http://www.unix.com/shell-programming-and-scripting/158315-replace-string-contents-txt-file-containing-multiple-lines-strings.html

share|improve this answer
    
I appreciate that you took the time to provide two solutions. Thank you. –  Sam Aug 26 at 3:45
    
@Ramesh: This awk won't work if line have something like QWERTY PATTERN. It skip the whole line instead of replace PATTERN. –  cuonglm Aug 26 at 5:13

In:

sed "s/PATTERN/`cat replacement.txt`/g" "openfile.txt"

' and " should not be a problem. Those are not special to sed. What should be a problem is &, \, / and newline. You can escape those with another sed command:

sed "s/PATTERN/$(sed 's@[/\&]@\\&@g;$!s/$/\\/' replacement.txt)/g" openfile.txt

Note that it removes the trailing newline characters in replacement.txt. If that's not want you want, you can do

replacement=$(sed 's@[/\&]@\\&@g;s/$/\\/' replacement.txt; echo .)
replacement=${replacement%.}
sed "s/PATTERN/$replacement/g" openfile.txt
share|improve this answer

With GNU sed you can just execute cat at whatever point of the script you like. Unlike r - which schedules for output for the end of the line cycle (which can be very frustrating!), e works like i or c in that it immediately writes its output. Here are some examples of its use:

printf %s\\n 'these are some words' \
    'that will each appear' \
    'on their own line' | 
    sed 's/.*words/echo & ; cat file/e'
these are some words
these
are
some
more
words    
that
are
stored
in
a
file
that will each appear
on their own line

And here's how you might use this:

printf %s\\n 'these are some words' \
    'that will each appear' \
    'on their own line' | 
sed 's/\(.*\)\n*words/\1\n&/;//P;s//\ncat file/ep;s/.*\n//'
these are some 
these
are
some
more
words
that
are
stored
in
a
file
that will each appear
on their own line
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.