我想使用正则表达式删除bash中的XML注释(awk,sed,grep ...) 我已经看过其他有关此事的问题,但他们遗漏了一些东西。这是我的xml代码
<Table>
<!--
to be removed bla bla bla bla bla bl............
removeee
to be removeddddd
-->
<row>
<column name="example" value="1" ></column>
</row>
</Table>
所以我正在比较2个xml文件,但我不希望比较考虑到这些评论。我这样做
diff file1.xml file2.xml | sed '/<!--/,/-->/d'
但只删除以<!--
开头的行和最后一行。它不会删除其间的所有行。
答案 0 :(得分:6)
最后,您将不得不向您的客户/朋友/教师推荐他们需要安装某种XML处理器。 xmlstarlet
是一个很好的命令行工具,但是有任何数量(或至少一些数量大于2)的XSLT实现可以为任何标准Unix编译,在大多数情况下也适用于Windows。你真的不能用基于正则表达式的工具进行大量的XML处理,无论你做什么都会很难阅读,难以维护,并且可能在极端情况下失败,有时会带来灾难性的后果。
我没有花很多时间来完善或审查以下的小awk程序。我认为它将从兼容的xml文档中删除注释。请注意,以下注释不符合:
<!-- XML comments cannot include -- so this comment is illegal -->
我的脚本无法正确处理它。
以下内容也是非法的,但由于我在野外看到它并且不难处理,我这样做了:
<!-------------- This comment is ill-formed but... -------------->
在这里。没有保证。我知道这很难读,我也不想维持它。任意角落情况都可能失败。
awk 'in_comment&&/-->/{sub(/([^-]|-[^-])*--+>/,"");in_comment=0}
in_comment{next}
{gsub(/<!--+([^-]|-[^-])*--+>/,"");
in_comment=sub(/<!--+.*/,"");
print}'
答案 1 :(得分:3)
xmlstarlet ed -d '//comment()' file.xml
答案 2 :(得分:2)
从我可以提出的文本文件中删除所有注释的最简单的解决方案是:
sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' | grep -zv '^<!--' | tr -d '\0'
解释:
sed
会输入null
这样的字符:
<Table>
\0<!--
to be removed bla bla bla bla bla bl............
removeee
to be removeddddd
-->\0
<row>
<column name="example" value="1" ></column>
</row>
</Table>
比grep -z
将该字符视为“行分隔符”
<Table>\n
<!--\n to be removed bla bla bla bla bla bl............\n\n removeee\n\n to be removeddddd\n -->
\n\n<row>\n <column name="example" value="1" ></column>\n </row>\n</Table>\n
grep -v
将删除中间部分。
最后tr -d
会再次移除\0
。
在这种情况下,它应该在比较之前应用于两个文件,例如:
diff <(sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' file1.xml | grep -zv '^<!--' | tr -d '\0') <(sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' file2.xml | grep -zv '^<!--' | tr -d '\0')
或更可读的功能:
stripcomments() {cat "$@" | sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' | grep -zv '^<!--' | tr -d '\0'}
diff <(stripcomments file1.xml) <(stripcomments file2.xml)
理论上可能存在CDATA块的一些问题,因为它们可用于具有不平衡的注释,并且它们具有重要的空字符的可能性更高,但我在现实生活中从未见过这样的xml文件
因此,对于大多数有效的xml文件,这应该可行。
答案 3 :(得分:0)
你可以使用这对&perl-xmllint&#39;完成这项工作:
{{1}}
使用Start =您的开始评论(在我们的案例中&lt;! - ) 结束=您的结束评论(在我们的案例中 - &gt;)
我尝试使用grep -vP没有任何好结果,因为我没有找到如何告诉grep将点理解为新行(s修饰符)。
答案 4 :(得分:0)
sed '/<!--/,/-->/d' server.xml
说明:
d - 删除
// - 到模式 -->