使用 Unix 命令在 `xml` 中查找空标签

使用 Unix 命令在 `xml` 中查找空标签

生成的文件xml带有空标签,如下所示

<headertag>
</headertag>

它位于连续的行中,我通常使用 perl 脚本根据标签之间的换行符作为模式 (\n) 来查找它,但我现在使用的 Unix 环境不支持此 perl 脚本。使用 sed 进行了相同的尝试,但我找不到在大.xml文件中存在这样的空标记的位置(行号)。有没有解决方案可以使用sedor找到这个awk

答案1

要解析 XML,请使用 XML 感知工具。我知道您说过您对所使用的系统有限制,但我将为您提供一个解决方案,一旦您说服您的经理,该解决方案就会起作用/无论是为了稳健可靠的操作,您都需要安装 XMLStarlet 才能正确执行XML 解析。

使用 XMLStarlet,给定 XML 文件

<?xml version="1.0"?>
<root>
  <headertag>
    <subtag/>
  </headertag>
  <headertag>
    <subtag>Don't delete me!</subtag>
  </headertag>
  <headertag>
</headertag>
  <headertag>
Not empty
</headertag>
</root>

以下内容将删除所有空标签,无论它们的名称是什么或它们出现在文档中的位置:

$ xmlstarlet ed -d '//*[not(normalize-space())]' file.xml >newfile.xml

$ cat newfile.xml
<?xml version="1.0"?>
<root>
  <headertag>
    <subtag>Don't delete me!</subtag>
  </headertag>
  <headertag>
Not empty
</headertag>
</root>

xmlstarlet命令有时可能会被调用,具体xml取决于它在您的系统上的打包方式。

XMLStarlet 可在此处获取:http://xmlstar.sourceforge.net/ ...但是先看看您的默认包管理器是否有它。

答案2

假设:

  • 我们要查找的空标签本身就在一行上。
  • 结束标签也位于其自己的行上+它紧随其后。
  • 假定空白由空格组成,而不是制表符。

sed -ne '
   /^ *\(<[^><]*>\) *$/!d                                   # tag opening should be on a line of its own
   s//\1/                                                   # strip away all whitespace
   $d; N                                                    # if the tag opening is on the last line, we dont need it. Otherwise, we grab the next line
   s/^.\(.*\).\n *<\/\1> *$/Empty tag: <\1> on line num\#/p # print only in case the tagnames match across lines => we have found an empty tag
   /\n/!=                                                   # print empty tag line num
   D                                                        # delete the pattern space
' yourfile.xml

答案3

您还没有告诉我们您想如何处理空标签。因此,我假设您希望将此类标签对转换为以下格式<headertag/>

这是一个简单的sed脚本,它将完全针对您提供给我们的示例案例执行此操作:

sed -E ':a;N;$!ba;s#<([^>]+)>\n</\1>#<\1/>#g' infile > outfile

答案4

您可以使用“pcregrep”代替 grep,它支持多行模式并且有更多选项。

此模式查找包含开始和结束标记的两个连续行:

pcregrep -M -v "<headertag>\n\s*?</headertag>" file
  • 其中 -M 代表多行
  • -v 代表反向匹配
  • \n 是 pcregrep 支持的换行符,但 grep 不支持(我认为)
  • \s 是空格字符。
  • *?任何字符

此模式会删除所有空标签。

相关内容