简体   繁体   中英

Bash Using Sed on a Variable

I have an xml file which will always have the following block inside of it:

<Name NameType="Also Known As">
  <NameValue>
    <FirstName>name1</FirstName>
    <Surname>sur1</Surname>
  </NameValue>
  <NameValue>
    <FirstName>name2</FirstName>
    <Surname>sur2</Surname>
  </NameValue>
</Name>

There may be just one "NameValue" node inside this block or there may be many. My issue is that I only ever want to keep the first one and discard the rest. The example above would hence read:

<Name NameType="Also Known As">
  <NameValue>
    <FirstName>name1</FirstName>
    <Surname>sur1</Surname>
  </NameValue>
</Name>

I'd like to use sed for this purpose. I have written the above block to a variable and tried to manipulate that as follows:

var=$(sed -n '/<Name NameType="Also Known As">*/,/<\/Name>/p' $file)
sed -i 's/<\/NameValue>.*<\/Name>/<\/NameValue><\/Name>/g' "$var"

I get the following in return:

sed: can't read <Name NameType="Also Known As">...

I thought the above would have replaced everything between the first closing NameValue tag and the closing Name tag with nothing. I used the -i option as I want to save the changes to this file. Perhaps it's syntax related, or maybe my understanding of using the sed command on a variable is way off. A point to note is that these tags occur inside other nodes in the file and so doing one blanket update using sed would change blocks which i don't want to change. This is the reason I passed this block to a variable. Any pointer's in the right direction would be much appreciated.

As the previous comments point out, sed expects one or several input files (which may be something like stdin, of course). In your example code, you read the content of a file into a variable in a roundabout way, and then use that variable as the name of a file. That is bound to fail. While I'm sure you could achieve your objectives using sed , I do not advise it. Branching in sed is horrible. Use a more powerful tool, preferably xsltproc or something else that is designed to work with XML.

You could use a stylesheet similar to this:

<?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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM