Bash在变量上使用Sed

时间:2016-04-15 00:14:55

标签: bash sed

我有一个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进行一次全面更新会改变我不想改变的块。这就是我将此块传递给变量的原因。任何指针都在正确的方向将非常感激。

1 个答案:

答案 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>