How to replace a multi line string in a bunch file

2020-03-04 12:52发布

问题:

#!/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.

回答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)



回答2:

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.



标签: linux bash