3

我想使用正则表达式(awk、sed、grep ...)删除 bash 中的 XML 注释我已经查看了其他关于此的问题,但他们缺少一些东西。这是我的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'

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

4

6 回答 6

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}'
于 2013-10-07T19:21:43.193 回答
5

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

sed 's/<!--/\x0<!--/g;s/-->/-->\x0/g' | grep -zv '^<!--' | tr -d '\0'

解释:

将输入这样sednull字符:

<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 文件,这应该可以工作。

于 2017-03-29T07:26:19.093 回答
3
xmlstarlet ed -d '//comment()' file.xml
于 2013-10-07T18:03:16.753 回答
1

您可以使用“perl-xmllint”对来完成这项工作:

cat yourFile.xml | perl -e 'while (<>) { next if (/Start.*End/ );if (/Start/) { while (<>) {last if (/End/) }}else {print "$_"; }} ' | xmllint --format -

开始 = 您的开始评论(在我们的例子中 <!--)结束 = 您的结束评论(在我们的例子中 -->)

我尝试使用 grep -vP 没有任何好的结果,因为我没有找到如何告诉 grep 将点理解为换行符(s 修饰符)。

于 2016-08-09T14:03:01.490 回答
0
 sed  '/<!--/,/-->/d' server.xml

解释:

d - 删除

/<!--/ - 从模式开始 <!--

/-->/ - 到模式 -->

于 2021-05-13T04:56:31.103 回答
0

此脚本使用 sed 来处理替换。

sed -E  -e\
':start
/<!--/ {
   :loop
   /-->/ {
            s/-->/mockend102499883356/
            s/<!--.*mockend102499883356//
            /<!--/ {
                   b loop
            }
            b done
   }
   :add
   N
   b loop
   :done
}'  filename.xml;

顺便说一下,这是一个 gnu sed 版本。如果不。它可能不起作用。

于 2021-10-31T17:02:00.087 回答