2014-09-22 148 views
2

这个问题已经是discussed here,但我注意到最流行的答案实际上是错误的,并且由于该页面仍然在谷歌中弹出#1,我认为这是有道理的评论。我不能在原来的讨论中发表评论,因为我的声誉太低,所以如果管理员认为它应该移到那里,请这样做,不要让我太难过)使用sed删除html评论标签

因此,我们要删除所有内容,这是由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 <[email protected]> 

/<!--/!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

是(通过使用SED缓冲/内存的限制),但两个版本都无法处理两个同一行上的注释:' keepme ' – 2014-09-22 14:58:29

+2

[义务链接](http://stackoverflow.com/a/1732454/7552) - 您应该使用HTML解析器删除HTML注释。 – 2014-09-22 16:10:45

+0

卡西米尔,你是对的,但我不知道如何修改脚本。据我了解,问题出现是因为sed正则表达式很贪婪。这是否意味着在sed html注释删除脚本中写入是不可能的? – 2014-09-22 16:43:59

回答

0
sed -n 'H 
$ {g 
    s/<\!--/²/g;s/-->/³/g 
:a 
    s/²[^³]*³//g 
    t a 
    s/.//p 
    }' YourFile 
  • 假设²³不内部使用的HTML(如果使用的话,改变定界符或adapte代码由一个替换字符串改变任何出现时和回的端部)
  • 不照顾html标记的像" blabla <!--
  • 任何嵌套级别是考虑到字符串