【发布时间】:2014-11-16 14:03:38
【问题描述】:
问题已经是discussed here,但我注意到最受欢迎的答案实际上是错误的,并且由于页面仍然在谷歌中弹出#1,我认为对此发表评论是有意义的。我无法在最初的讨论中发表评论,因为我的声誉太低了,所以如果管理员认为应该将其移到那里,请这样做,不要太折磨我))
所以,我们要删除所有内容,用 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 代码相比,此解决方案会慢一些,因为正则表达式将被搜索多次,即使它不存在,而第一个脚本仅在肯定存在时才运行搜索正则表达式。
【问题讨论】:
-
可以,但是两个版本无法处理同一行的两个cmets:
<!--abcd-->keepme<!--efgh--> -
obligatory link -- 您应该使用 HTML 解析器来删除 HTML cmets。
-
Casimir,你是对的,但我不知道如何修改脚本。据我了解,问题的出现是因为 sed 正则表达式是贪婪的。是不是说在sed html cmets移除脚本中写不出来?
-
我would use
tidy -quiet -xml --hide-comments 1.