【发布时间】:2013-08-01 10:19:46
【问题描述】:
我有一些带有这样标签的 xml 文件:
<?xm-insertion_mark_start author="some_author" time="20050602T125956-0500"?>
我将如何剥离此类插入物?我试过这个有用:
sed -e 's/<\?xm.*?\?>//g' in.xml > out.xml
【问题讨论】:
标签: xml xml-parsing sed
我有一些带有这样标签的 xml 文件:
<?xm-insertion_mark_start author="some_author" time="20050602T125956-0500"?>
我将如何剥离此类插入物?我试过这个有用:
sed -e 's/<\?xm.*?\?>//g' in.xml > out.xml
【问题讨论】:
标签: xml xml-parsing sed
sed 没有不情愿(“非贪婪”)量词。试试这个:
sed '/<?xm\([^?][^>]\)\+?>/d' in.xml > out.xml
编辑:当然,您可以使用 XSLT 从 XML 中安全地删除处理指令 (PI)。
这将删除所有名为 xm-insertion_mark_start 的 PI,但保留所有剩余的 XML 不变。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="processing-instruction('xm-insertion_mark_start')" />
</xsl:stylesheet>
使用
<xsl:template match="processing-instruction()" />
如果您想删除所有个 PI,无论其名称如何。
您可以使用xsltproc(1) 在命令行上将转换应用到您的 XML。
【讨论】:
sed 中,? 不是元字符。你必须让它不转义才能从字面上匹配它。括号是元字符,因此您需要对它们进行转义,+ 也是如此。
)、( 和 + 必须转义以应用其特殊含义。也许我之前的评论说错了,对不起。在不转义它们的情况下,它们匹配文字,与? 相同。作为替代,使用--regex-extended 可以让您使用?、+、( 和) 而无需转义,就像大多数其他语言的正则表达式风格(并且您的第一个版本已经使用它)。
*、零宽度断言等等,否则所有都逃脱了。
使用 sed 的 delete (d) 命令代替替换 (s):
也可以像这样使用sed -i(内联):
sed -i.bak '/<?xm.*?>/d' in.xml
使用 grep:
grep -v '<\?xm.*\?>' in.xml > out.xml
警告:shell 实用程序并不总是解析和编辑 XML 数据的最佳工具。
【讨论】:
? 匹配的 \? 被转义。
.*,它可以并且将销毁XML文件(如果它包含多个处理指令)。
<?xm...?> 以上行有换行符、换行符怎么办?
\n 以外的其他内容才能使其工作。由于 XML 不能合法包含,比如\0x8,您可以将其用作行分隔符并将文件作为单行处理。 (我不知道这是否容易实现 - this answer 建议通过 tr 用管道替换 \n 与 sed 无法识别的东西)
? 不是sed 的元字符。不要逃避它以匹配字面意思。