Issue
I'm trying to write a sed
script that replaces the text enclosed between two markers with the contents of another file.
Say I have the following file with the markers <!-- Start -->
and <!-- End -->
:
# index.html
...
<!-- Start -->
<p>Old content</p>
<!-- End -->
...
And I want to replace the enclosed text with the content of this file:
# snippet.html
<p>New content</p>
I tried this sed
script:
$ cat snippet.html | sed -i -e '/<\!-- Start -->/,/<\!-- End -->/ { r /dev/stdin' -e';d};' index.html
It replaces both the content and the markers, but I need to keep the <!-- Start -->
and <!-- End -->
markers so I can replace the content again in the future.
What changes should I make to the sed
script?
Thanks in advance!
Solution
All that you need to do to your code is add //!
before the d
:
cat snippet | sed -e '/<\!-- Start -->/,/<\!-- End -->/ { r /dev/stdin' -e '; //!d }' file
//
is shorthand for "last match" ... so in the case of /START/,/END/{ }
without any other match within { }
, it will match both /START/
and /END/
.
//!d
ensures that the range, excepting the matching lines at the start and end, will be deleted.
ETA: as @potong raised in the comments, the use of r /dev/stdin
seems to be a special case-- only the first r
will add anything to the output stream.
Answered By - stevesliva Answer Checked By - David Marino (WPSolving Volunteer)