在bash中使用Regex删除XML注释

Mas*_*ter 2 regex xml 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>
Run Code Online (Sandbox Code Playgroud)

所以我正在比较2个xml文件,但我不希望比较考虑到评论.我这样做

diff file1.xml file2.xml | sed '/<!--/,/-->/d'
Run Code Online (Sandbox Code Playgroud)

但这只删除了<!--以及最后一行开头的行.它不会删除其间的所有行.

ric*_*ici 6

最后,您将不得不向您的客户/朋友/教师推荐他们需要安装某种XML处理器.xmlstarlet是一个很好的命令行工具,但是有任何数量(或至少一些数量大于2)的XSLT实现,可以为任何标准Unix编译,在大多数情况下也适用于Windows.你真的不能用基于正则表达式的工具做很多的XML处理,无论你做什么都会很难阅读,难以维护,并且可能在极端情况下失败,有时会带来灾难性的后果.

我没有花很多时间来抛光或审查下面的小awk程序.我认为它将从兼容的xml文档中删除注释.请注意,以下注释符合要求:

<!-- XML comments cannot include -- so this comment is illegal -->
Run Code Online (Sandbox Code Playgroud)

并且我的脚本无法正确处理它.

以下也是非法的,但是因为我在野外看到它并不难处理,我这样做了:

<!-------------- This comment is ill-formed but... -------------->
Run Code Online (Sandbox Code Playgroud)

这里是.没有保证.我知道这很难读,我也不想维持它.它可能会在任意角落情况下失败.

awk 'in_comment&&/-->/{sub(/([^-]|-[^-])*--+>/,"");in_comment=0}
     in_comment{next}
     {gsub(/<!--+([^-]|-[^-])*--+>/,"");
      in_comment=sub(/<!--+.*/,"");
      print}'
Run Code Online (Sandbox Code Playgroud)


Sam*_*ner 5

从我能想出的文本文件中删除所有注释的最简单的解决方案是:

sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' | grep -zv '^<!--' | tr -d '\0'
Run Code Online (Sandbox Code Playgroud)

解释:

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>
Run Code Online (Sandbox Code Playgroud)

比将该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')
Run Code Online (Sandbox Code Playgroud)

或更易读的函数:

stripcomments() {cat "$@" | sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' | grep -zv '^<!--' | tr -d '\0'}

diff <(stripcomments file1.xml) <(stripcomments file2.xml)
Run Code Online (Sandbox Code Playgroud)

从理论上讲,CDATA 块可能存在一些问题,因为它们可用于具有不平衡的注释,并且它们具有重要的空字符的可能性更高,但我在现实生活中从未见过这样的 xml 文件。

所以对于大多数有效的 xml 文件,这应该有效。

  • 这对于您想做的大多数事情来说已经足够了。 (2认同)