Git Bashを使用して、何百ものファイルのyrotタグの内容を条件付きで置き換えようとしています。ただし、その内容がホイール関連部品名タグに属する場合にのみ可能です。
// YES, change
<part name="D_wheel1" seqNumber="1" >
<yrot min="0.000000" max="0.000000" cur="0.000000" />
</part>
// YES, change
<part name="D_wheel2" seqNumber="1" >
<yrot min="0.000000" max="0.000000" cur="0.000000" />
</part>
// NO, don't change
<part name="door" seqNumber="1" >
<yrot min="0.000000" max="0.000000" cur="0.000000" />
</part>
// Example Line Change
// From: <yrot min="0.000000" max="0.000000" cur="0.000000" />
// To: <yrot min="INF" max="INF"/>
awkのようなツールを使用すると、これは可能ですか?それとも特別なXMLパーサーを使用する必要がありますか?
編集:明確に言えば、に属するタグは約12個あり、そのうちの1つはタグ内にのみ表示されます。名前に「wheel」が含まれている場合にのみ行を変更したいと思います。それ自体が入れ子になっています。
XMLパーサーが必要であると主張する人にとって、条件が満たされている場合(yrotタグがホイールにある)、単純なテキストの検索/置換が機能しないのはなぜですか?確認はとても難しいですか?
ベストアンサー1
XMLを次data.xml
のように提供します。
$ cat data.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<part name="D_wheel1" seqNumber="1">
<yrot min="0.000000" max="0.000000" cur="0.000000" />
</part>
<part name="D_wheel2" seqNumber="1">
<yrot min="0.000000" max="0.000000" cur="0.000000" />
</part>
<part name="door" seqNumber="1">
<yrot min="0.000000" max="0.000000" cur="0.000000" />
</part>
</root>
xmlstarlet
そして使用Xパス:
$ xmlstarlet ed \
--var target '//part[contains(@name, "wheel")]/yrot' \
-u '$target/@*[name()="min" or name()="max"]' -v 'INF' \
-d '$target/@cur' data.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<part name="D_wheel1" seqNumber="1">
<yrot min="INF" max="INF"/>
</part>
<part name="D_wheel2" seqNumber="1">
<yrot min="INF" max="INF"/>
</part>
<part name="door" seqNumber="1">
<yrot min="0.000000" max="0.000000" cur="0.000000"/>
</part>
</root>
または古典的な方法を使用してくださいXSLT:およびxsltproc
/またはxmlstarlet
$ cat data.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[contains(@name, 'wheel')]/yrot">
<xsl:copy>
<xsl:attribute name="min">INF</xsl:attribute>
<xsl:attribute name="max">INF</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
$ xsltproc data.xsl data.xml #or: xmlstarlet tr data.xsl data.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<part name="D_wheel1" seqNumber="1">
<yrot min="INF" max="INF"/>
</part>
<part name="D_wheel2" seqNumber="1">
<yrot min="INF" max="INF"/>
</part>
<part name="door" seqNumber="1">
<yrot min="0.000000" max="0.000000" cur="0.000000"/>
</part>
</root>