3
#!/bin/sh
old="hello"
new="world"
sed -i s/"${old}"/"${new}"/g $(grep "${old}" -rl *)

The preceding script just work for single line text, how can I write a script can replace a multi line text.

old='line1
line2
line3'

new='newtext1
newtext2'

What command can I use.

tomnotcat
  • 231
  • 3
  • 9
  • possible duplicate of [sed and awk: how to replace a section of file to another content?](http://stackoverflow.com/questions/4311915/sed-and-awk-how-to-replace-a-section-of-file-to-another-content) – parvus Oct 17 '13 at 05:38

2 Answers2

1

awk can do that for you.

awk 'BEGIN { RS="" }
  FILENAME==ARGV[1] { s=$0 }
  FILENAME==ARGV[2] { r=$0 }
  FILENAME==ARGV[3] { sub(s,r) ; print }
' FILE_WITH_CONTENTS_OF_OLD FILE_WITH_CONTENTS_OF_NEW ORIGINALFILE > NEWFILE

But you can do it with vim like described here (scriptable solution).

Also see this and this in the sed faq.

Community
  • 1
  • 1
Zsolt Botykai
  • 50,406
  • 14
  • 85
  • 110
1

You could use perl or awk, and change the record separator to something else than newline (so you can match against bigger chunks. For example with awk:

echo -e "one\ntwo\nthree" | awk 'BEGIN{RS="\n\n"} sub(/two\nthree\n, "foo")'

or with perl (-00 == paragraph buffered mode)

echo -e "one\ntwo\nthree" | perl -00 -pne 's/two\nthree/foo/'

I don't know if there's a possibility to have no record separator at all (with perl, you could read the whole file first, but then again that's not nice with regards to memory usage)

Jo So
  • 25,005
  • 6
  • 42
  • 59