1

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, 2023 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, 2023 at 3:31

4 Answers 4

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, 2023 at 18:18
1

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).

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

W3C's HTML-XML-utils are HTML-aware and / or XML-aware. The hxincl utility from the html-xml-utils package expands certain embedded comments or prints a makefile rule listing the dependent include files.

hxincl -s incfnm='file2.txt' file1.html

generates the desired output given a slightly modified input:

    <!-- begin-include "incfnm" -->

<p>more text1</p>
<p>more text2</p>
    <!-- end-include "incfnm" -->

You must log in to answer this question.

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