使用sed删除html评论标签

时间:2014-09-22 14:46:07

标签: regex bash sed

问题已经是discussed here,但我注意到最受欢迎的答案实际上是错误的,而且由于该网页在Google中仍然排名第一,我认为对此进行评论是有意义的。我不能在原来的讨论中发表评论,因为我的声誉太低了,所以如果管理员认为应该把它移到那里,请这样做,不要太费力地贬低我))

所以,我们要删除所有内容,用html注释标记

表示
This is how my text (html) file looks like
<!--
 |                                |
 |  This is a dummy comment       |
 |      please delete me          |
 |         asap                   |
 |                                |
  ________________________________
 | -->

投票最多的答案建议使用以下代码

#! /bin/sed -f
# Delete HTML comments
# i.e. everything between <!-- and -->
# by Stewart Ravenhall <stewart.ravenhall@ukonline.co.uk>

/<!--/!b
:a
/-->/!{
    N
    ba
}
s/<!--.*-->//

虽然它在简单的情况下起作用,但当另一个评论从同一行开始时,它会失败,前一个评论结束。例如,输入

<!--
1 --><!--
2 --><!--
3
-->

应用上面的脚本后,会给出

<!--
2 --><!--
3
-->

表示只会删除第一条评论。原因是在应用替换命令后,代码不会检查缓冲区是否还有下一个注释的起始标记。

解决这个问题的方法是修改像这样的代码

#! /bin/sed -f
:x
/<!--/!b
:a
/-->/!{
    N
    ba
}
s/<!--.*-->//
bx

或者,用简短的符号

cat file.html | sed ':x;/<!--/!b;:a;/-->/!{N;ba};s/<!--.*-->//;bx'

我认为更正此脚本很重要,因为它列在seder's grab bag

Brian Clements提出了一个更简洁,更优雅的解决方案(我已对其进行了一些修改)

cat file.html | sed ':a;s/<!--.*-->//g;/<!--/{N;ba}'

这个工作正常,因为即使在替换完成后,代码也会检查下一个注释的开头是否存在。然而,在我看来(如果我错了,请纠正我)这个解决方案与修改后的Stewart Ravenhall代码相比会慢一点,因为正则表达式将被搜索多次,即使它不存在,而第一个脚本只在肯定存在时才运行正则表达式的搜索。

1 个答案:

答案 0 :(得分:0)

sed -n 'H
$ {g
   s/<\!--/²/g;s/-->/³/g
:a
   s/²[^³]*³//g
   t a
   s/.//p
   }' YourFile
  • 假设{h}内未使用²³(如果使用,则更改分隔符或调整代码以通过替换字符串更改任何出现,并返回到最后)
  • 请不要像" blabla <!--
  • 这样的字符串中处理html标记
  • 考虑任何嵌套级别(受使用的sed缓冲区/内存限制)