4

All is said in the title , I want to replace all lines between two patterns with a a file content.

file1

line 1
line 2
foo
foobar
bar
line 6
line 7

file2

line 3
line 4
line 5

desired file

line 1
line 2
line 3
line 4
line 5
line 6
line 7

Tried many sed commands nothing works for me , closest command below successfully matchs lines between foo and bar but replace them with "$(cat file2)" string and not file content.

sed '/foo/{:a;N;/bar/!ba;N;s/.*\n/$(cat file2)/};p' file1
1
  • Here is a ugly workaround: printf '%s\n' "$(sed '/^foo$/,$d' file1 && cat file2 && sed -e '/^bar$/,$!d' -e '/^bar$/d' file1)" > desired-file or (sed '/^foo$/,$d' file1 && cat file2 && sed -e '/^bar$/,$!d' -e '/^bar$/d' file1) > desired-file
    – pa4080
    Jan 29, 2018 at 17:39

1 Answer 1

3

You are close, I think - your main issue is that $(cat file2) is going to be treated as literal within single quotes - you should be using the built-in r command:

r filename

Queue the contents of filename to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read. Note that if filename cannot be read, it is treated as if it were an empty file, without any error indication.

So:

sed '
  /foo/{
    :a
    N
    /\nbar$/!ba
    r file2
    d
  }
' file1

If you want to wrangle this into a one-liner there's a trick you'll need to prevent sed from treating everything after the r as part of the filename:

sed -e '/foo/{:a; N; /\nbar$/!ba; r file2' -e 'd;}' file1
1
  • +1 as it works for the generic example above .. God knows why it didn't work for my xml files.. managed to find another way to solve my problem though thanks for helping.
    – storm
    Jan 31, 2018 at 14:04

You must log in to answer this question.

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