11

Lets say i have two files foo and bar. I want a replace the string "this is test" in foo with the contents of the file bar. How can i do this using a one liner sed?

I have used:

sed -i.bak 's/this is test/$(cat bar)\n/g' foo 

but the the string is being replaced by literal $(cat bar) rather than the contents of bar. I have tried using quotations but the result remains the same.

Radu's answer is correct as far as the quote is concerned. Now the problem is lets say my bar file contains:

this
is
a
test
file

Now if i run the command it gives an error:

sed: -e expression #1, char 9: unterminated `s' command

18 times.

9
  • does the contents of the file bar contains newline characters? Oct 23, 2014 at 10:58
  • @AvinashRaj: Yes.
    – heemayl
    Oct 23, 2014 at 10:59
  • @AvinashRaj: please check my edits.
    – heemayl
    Oct 23, 2014 at 11:06
  • Does it have to be sed? To avoid escaping issues, I'd rather use another scripting language that is better suited for file interaction like Awk, Python, Perl, Ruby, or whatnot. Oct 23, 2014 at 13:13
  • I was trying to check this using sed. So it would be great if a solution is available in Sed.
    – heemayl
    Oct 23, 2014 at 13:16

3 Answers 3

10

The following command should work for what you want:

sed "s/this is test/$(cat bar)/" foo

If foo contain more then one line, then you can use:

sed "s/this is test/$(sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' bar | tr -d '\n')/" foo

or:

sed -e '/this is a test/{r bar' -e 'd}' foo

Source of the last two commands: Substitute pattern within a file with the content of other file

To make the change in foo file, use sed -i.

9
  • 1
    it's not working for me.. Oct 23, 2014 at 11:11
  • @Radu: Please check my edits. I have tried this already.
    – heemayl
    Oct 23, 2014 at 11:12
  • @heemayl you used the wrong quotes.
    – muru
    Oct 23, 2014 at 11:20
  • @heemayl No, you tried using simple quotes, in my answer I used double quotes. See Difference between single and double quotes in bash. Single quotes won't interpolate anything, but double quotes will (for example variables, backticks, certain \ escapes, etc...) Oct 23, 2014 at 11:21
  • 1
    I don't know if your answer is correct since the OP's question said replace the string "this is test" and not replace the line "this is test". If the line is "this is test in foo file" in foo file, then you deleted "in foo file" string at the end of that line(in your second command). but he/she marked as answer then I think the "this is test" is in a separate line not string into line but again title says that is STRING. Oct 23, 2014 at 12:42
6

One way:

sed -e '/this is test/r bar' -e '/this is test/d' foo

Sample result:

$ cat bar
12
23
$ cat foo
ab
this is test
cd
this is test
ef
$  sed -e '/this is test/r bar' -e '/this is test/d' foo
ab
12
23
cd
12
23
ef
8
  • Not working in my case.
    – heemayl
    Oct 23, 2014 at 11:44
  • "Not working" means error or result not as expected or something else?
    – Guru
    Oct 23, 2014 at 11:45
  • Same mentioned error i.e. sed: -e expression #1, char 9: unterminated `s' command
    – heemayl
    Oct 23, 2014 at 11:46
  • Can you tell me please what /r is doing here?
    – heemayl
    Oct 23, 2014 at 12:07
  • @heemayl r - append file to stdout after flush. See unix.stackexchange.com/a/26290/37944 Oct 23, 2014 at 12:10
1

When you need to replace an entire line with the contents of a file, you can use r to insert a file and d to delete the current line:

sed -e "/regex/{r/path/to/file" -e "d}"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .