在bash中使用Regex删除XML注释

时间:2013-10-07 16:52:58

标签: xml regex bash

我想使用正则表达式删除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'

但只删除以<!--开头的行和最后一行。它不会删除其间的所有行。

5 个答案:

答案 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 - 删除

// - 到模式 -->