Bash xml文件替换awk

Bash xml文件替换awk,bash,awk,Bash,Awk,我只需要为JOBNAME=“NSVN1QU1”替换TASKTYPE值 我用这个: awk -v jobname="NSVN1QU1" -v tasktype="vvvvvv" '$0 ~ "JOBNAME`enter code here`=\"" jobname "\"" { sub(/TASKTYPE="[^"]*"/, "TASKTYPE=\"" tasktype "\"") } 1' "$out" > "$tmp" 输入数据: <JOB JOBNAME="NSVN1Q

我只需要为JOBNAME=“NSVN1QU1”替换TASKTYPE值

我用这个:

awk -v jobname="NSVN1QU1" -v tasktype="vvvvvv" '$0 ~ "JOBNAME`enter code here`=\"" jobname "\"" { sub(/TASKTYPE="[^"]*"/, "TASKTYPE=\"" tasktype "\"") } 1' "$out" > "$tmp"
输入数据:

<JOB
    JOBNAME="NSVN1QU1"
    SYSDB="0"
    TASKTYPE="Command"
    USE_INSTREAM_JCL="N"
    WEEKDAYS="1,2,3,4,5,6">
    <ON AND_OR="A" CODE="NOTOK" STMT="*">
        <DOCOND NAME="ZGIF00P01NSVN1QU1-KO" ODATE="ODAT" SIGN="+"/>
    </ON>
</JOB>
<JOB
    JOBNAME="NSVN1999"
    SYSDB="0"
    TASKTYPE="Dummy"
    USE_INSTREAM_JCL="N"
    <INCOND AND_OR="A" NAME="ZGIF00P01NSVN1000-OK" ODATE="ODAT"/>
    <OUTCOND NAME="ZGIF00P01NSVN1999-OK" ODATE="ODAT" SIGN="+"/>
    <QUANTITATIVE NAME="QR-GIF00P000" ONFAIL="R" ONOK="R" QUANT="1"/>
</JOB>
<JOB 
    JOBNAME="NSVN1000"
    SYSDB="0"
    TASKTYPE="Dummy"
    USE_INSTREAM_JCL="N">
    <INCOND AND_OR="A" NAME="ZGIF00P01NSAV1999-OK" ODATE="ODAT"/>
    <OUTCOND NAME="ZGIF00P01NSVN1000-OK" ODATE="ODAT" SIGN="+"/>
    <QUANTITATIVE NAME="QR-GIF00P000" ONFAIL="R" ONOK="R" QUANT="1"/>
</JOB>


假设输入数据是有效的XML,为此使用适当的XML解析工具而不是awk。使用awk处理XML将导致脚本在XML格式以良性方式更改时崩溃,例如插入换行符或更改属性顺序。没有人希望他们的XML处理工具在发生此类更改时崩溃,因此最好使用为此目的编写的工具来处理XML

例如,使用
xmlstarlet
,您可以简单地编写:

xmlstarlet ed -u '//JOB[@JOBNAME="NSVN1QU1"]/@TASKTYPE' -v 'vvvvvv' file.xml
这里的
//JOB[@JOBNAME=“NSVN1QU1”]/@TASKTYPE
是一个XPath表达式,用于选择
作业
节点的
@TASKTYPE
属性,该节点的
JOBNAME
属性为
NSVN1QU1
。该命令将该属性的值更新为给定值
vv

附录:另一种更复杂的方法是使用以下样式表,这种方法将适用于每个XSLT处理器(在xmlstarlet因某种原因不可用的情况下):

<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="//JOB[@JOBNAME='NSVN1QU1']/@TASKTYPE">
    <xsl:attribute name="TASKTYPE">
      <xsl:value-of select="'vvvvvv'"/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

对于其他实用程序,请参阅其各自的手册页

其工作原理是

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

位复制给定的输入,除非声明了匹配的模板(在这种情况下应用了模板),并且

  <xsl:template match="//JOB[@JOBNAME='NSVN1QU1']/@TASKTYPE">
    <xsl:attribute name="TASKTYPE">
      <xsl:value-of select="'vvvvvv'"/>
    </xsl:attribute>
  </xsl:template>


模板在与以前相同的条件下进行与以前相同的转换。

这真的是输入数据吗?因为它不是有效的XML。第二个
作业
标记在任何地方都没有关闭,第一个
上的
标记格式不正确。这只是我的xml文件格式的一个示例…@rouis重点是,这是一个不完整的示例,这意味着设计用于处理xml的工具将无法正确处理它。你不应该用awk来做这件事。请尝试使用xmlstarlet之类的工具。我得到以下结果:./test.sh:第5行:xmlstarlet:command not foundSo…安装xmlstarlet。如果无法安装xmlstarlet,请提供其他解决方案??我添加了一种不太简洁的方法来做同样的事情。它可以与任何XSLT处理器一起使用。我确实希望您可以使用其中的一个,因为否则处理XML将是非常痛苦的。
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="//JOB[@JOBNAME='NSVN1QU1']/@TASKTYPE">
    <xsl:attribute name="TASKTYPE">
      <xsl:value-of select="'vvvvvv'"/>
    </xsl:attribute>
  </xsl:template>