使用sed删除多行HTML注释

使用sed删除多行HTML注释

这是我想出的,但它不适用于多行:

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

答案1

由于sed在默认模式下是逐行运行的,因此一种(诚然是混淆的)方法是\x00在将内容输入之前用其他字符(例如 NULL 字符)替换换行符sed

tr '\n' '\x00' <my_file

sed然后将内容视为一行。然而,

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

由于 的贪婪匹配性质,将不起作用sed。我们可以通过将注释中的所有内容匹配到第一个字符来实现非贪婪匹配<,但这只有在 HTML 注释不允许包含<字符(特别是其他 HTML 标签)时才有效,这是我们无法假设的。

为了解决这个问题,我们将序列转换<!为文件中其他地方未使用的单个字符,我们可以为此构造一个非贪婪匹配。我们将\x01为此目的选择特殊字符,<!在非贪婪匹配后将其转换回该特殊字符:

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

(请注意使用 shell 语法$''而不是''将文字单字节字符 \x01 传递给sed

在第三阶段,NULL 字符被转换回换行符:

tr '\x00' '\n'

最后,空行被另一个调用抑制sed

sed -e '/^$/d'

总之,

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'

如果您选择使用不同的工具(awkperl单行)而不是,则存在更优雅的解决方案sed,例如:

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

相关内容