This is what I came up with but it doesn't work with multiple lines:

sed -i '/<!-- my comment -->.*<!-- \/my comment end -->/d' my_file


Since sed in its default mode operates on a line-by-line basis, an (admittedly obfuscated) approach would be to replace the newline characters with something else (such as the NULL character \x00) before feeding the the content into sed:

tr '\n' '\x00' <my_file

sed then sees the content as one line. However,

sed -e 's/<!-- my comment -->.*<!-- \/my comment end -->//'

will not work due to the greedy matching nature of sed. We could implement a non-greedy match by matching everything inside the comment up to the first < character, but this would work only if HTML comments were not allowed to contain < characters (and, in particular, other HTML tags), which we cannot assume.

To solve this, we'll convert the sequence <! to a single character not used elsewhere in the file, for which we can construct a non-greedy match. We'll choose the special character \x01 for this purpose, which we convert back to <! after the non-greedy match:

sed -e $'s/<!/\x01/g' -e $'s/\x01-- my comment -->[^\x01]*\x01-- \/my comment end -->//g'

(note the use of the shell syntax $'' instead of '' to pass the literal single-byte character \x01 to sed)

In a third stage, the NULL characters are converted back into newlines:

tr '\x00' '\n'

And finally, empty lines are suppressed by another invocation of sed:

sed -e '/^$/d'

In summary,

tr '\n' '\x00' <my_file |sed -e $'s/<!/\x01/g' -e $'s/\x01-- my comment -->[^\x01]*\x01-- \/my comment end -->//g' |tr '\x00' '\n'|sed -e '/^$/d'

More elegant solutions exist if you choose to use different tools (awk or perl one-liners) instead of sed, such as:

perl -0pe 's/<!-- my comment -->.*?<!-- \/my comment end -->//gs' my_file

  • I changed my suggested answer to work around this. – Guido Mar 28 '16 at 4:48

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.