我有一个xml文件,其中总是包含以下块:
<Name NameType="Also Known As">
<NameValue>
<FirstName>name1</FirstName>
<Surname>sur1</Surname>
</NameValue>
<NameValue>
<FirstName>name2</FirstName>
<Surname>sur2</Surname>
</NameValue>
</Name>
可能只有一个&#34; NameValue&#34;这个块里面的节点或者可能有很多。我的问题是我只想保留第一个并丢弃其余部分。因此上面的例子如下:
<Name NameType="Also Known As">
<NameValue>
<FirstName>name1</FirstName>
<Surname>sur1</Surname>
</NameValue>
</Name>
我想为此目的使用sed。我已将上述块写入变量并尝试按如下方式操作:
var=$(sed -n '/<Name NameType="Also Known As">*/,/<\/Name>/p' $file)
sed -i 's/<\/NameValue>.*<\/Name>/<\/NameValue><\/Name>/g' "$var"
我得到以下回报:
sed: can't read <Name NameType="Also Known As">...
我认为上面的内容会替换第一个结束的NameValue标记和结束的Name标记之间的所有内容。我使用-i选项,因为我想将更改保存到此文件。也许它的语法相关,或者我对在变量上使用sed命令的理解是远离的。需要注意的是,这些标签出现在文件中的其他节点内,因此使用sed进行一次全面更新会改变我不想改变的块。这就是我将此块传递给变量的原因。任何指针都在正确的方向将非常感激。
答案 0 :(得分:1)
正如之前的评论所指出的,sed
需要一个或多个输入文件(当然可能类似于stdin)。在示例代码中,您以迂回方式将文件的内容读入变量,然后将该变量用作文件的名称。这肯定会失败。虽然我确信您可以使用sed
实现目标,但我不建议。在sed
中分支是可怕的。使用功能更强大的工具,最好是xsltproc
或其他旨在使用XML的工具。
您可以使用与此类似的样式表:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Name">
<Name>
<xsl:copy-of select="@*" />
<xsl:copy-of select="*[1]" />
</Name>
</xsl:template>
</xsl:stylesheet>