0

I have several files that all contain a string. This string needs to be replaced by the whole content of another file (that can possibly be multi-line). How can I do this?

What I need is something like sed -i 's/string/filename/' * where filename is an actual file and not the string "filename".

Additional info: The file can contain special characters such as / or \ or | or [ or ].

Thomas Dickey
  • 76,765
Foo Bar
  • 3,562

3 Answers3

2

bash works well for this:

$ cat replace
foo/bar\baz
the second line

$ cat file
the replacement string goes >>here<<

$ repl=$(<replace)

$ str="here"

$ while IFS= read -r line; do
    echo "${line//$str/$repl}"
done < file
the replacement string goes >>foo/bar\baz
the second line<<

Awk would work, except that it will interpret backslash escapes (the \b in my example)

$ awk -v string="here" -v replacement="$(<replace)" '
    {gsub(string, replacement); print}
' file
the replacement string goes >>foo/baaz
the second line<<
glenn jackman
  • 85,964
2

You need the underused sed command r which reads a file:

sed -i '/string/{r filename
                 d}'

I assume you want to replace the whole line, else replace d by something suitable.

meuh
  • 51,383
  • 1
    else there is nothing suitable as r always inserts a newline before the ouput of a read – don_crissti Jun 26 '15 at 16:25
  • correct: r ignores the pattern space, but you can remove the d and do (eg) s/string/something else/. This changed line will appear before the file contents. – meuh Jun 26 '15 at 16:34
  • 1
    The point was that you cannot insert the content of another file inline if you use r , no matter what you do. – don_crissti Jun 26 '15 at 16:37
  • gotcha. Might be adequate for the OP though. – meuh Jun 26 '15 at 17:02
  • The bash version from the accepted answer works best for me. Nevertheless, a +1 for you because I did not know about sed's r. – Foo Bar Jun 27 '15 at 08:36
0

I got this to work:

$ foo='baz'
$ echo "foobarbaz" | sed "s/foo/${foo}/"
bazbarbaz

Taking that one step further, your first line would be something like:

$ foo=`cat filename`

This assumes you know the filename before you reach the line to be replaced, of course - if you don't, you have to read the line, get the filename, then do the read-and-replace.

John
  • 17,011