0

I have a file1.html:

<!doctype html>
<html>
<head>
</head>
<body>
    text
    <!-- start-replacing -->
<p>more text1</p>
<p>more text2</p>
    <!-- end-replacing -->
    other text
</body>
</html>

and a file2.txt

<p>some text</p>
<div>some other text</div>

Now I'm looking for a command to replace everything between

<!-- start-replacing --> and <!-- end-replacing -->

with the content of file2.txt

the output.html should be:

<!doctype html>
<html>
<head>
</head>
<body>
    text
    <!-- start-replacing -->
<p>some text</p>
<div>some other text</div>
    <!-- end-replacing -->
    other text
</body>
</html>
2
  • 2
    edit your question to show what you've tried.
    – Ed Morton
    Feb 26 at 16:00
  • Parsing or modifying HTML (or any other kind of structured text such as XML or JSON) with regular expressions alone is extremely fragile, at best. Even tiny changes to the expected input will break your script. You should use a language with an HTML or XML parsing library - e.g. perl's HTML::Parser is one of several perl libraries that parses HTML into a perl object you can interact with as you would any other data object. Python and Java and C and many other languages have similar libraries.
    – cas
    Feb 27 at 3:31

3 Answers 3

4

With perl:

perl -0777 -pe '
  BEGIN{$repl = <STDIN>}
  s/<!-- start-replacing -->\K.*?(?=<!-- end-replacing -->)/$repl/sg
' file1.html < file2.txt > output.html
1
  • 2
    Or use -g instead of -0777 beginning with Perl 5.36 Feb 26 at 18:18
0

Using sed

$ sed -Ee '/start-replacing/{{r file2.txt' -e '};n;:a;N;s/.*\n(.*end-replacing[^\n]*\n)/\1/;ba}' file1.html
<!doctype html>
<html>
<head>
</head>
<body>
    text
    <!-- start-replacing -->
<p>some text</p>
<div>some other text</div>
    <!-- end-replacing -->
    other text
</body>
</html>
0

With GNU sed:

sed -e '/<!-- end-replacing -->/e cat file2.txt' -e '/<!-- start-replacing -->/,//{//!d}' file1.html

The e command is used to call the external command cat file2.txt on the ending address range. The file contents will be inserted before the matching line.

The lines between the address range is then deleted. // represents the last used regex (the ending range after the comma and both the addresses within the {} block).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.