生成的文件xml
带有空标签,如下所示
<headertag>
</headertag>
它位于连续的行中,我通常使用 perl 脚本根据标签之间的换行符作为模式 (\n) 来查找它,但我现在使用的 Unix 环境不支持此 perl 脚本。使用 sed 进行了相同的尝试,但我找不到在大.xml
文件中存在这样的空标记的位置(行号)。有没有解决方案可以使用sed
or找到这个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 是空格字符。
- *?任何字符
此模式会删除所有空标签。