sedを使用してxmlファイル内のn番目のパターンの発生を見つけて置き換える

sedを使用してxmlファイル内のn番目のパターンの発生を見つけて置き換える

私のovaには2つのvmdkファイルがあります。 ovf ファイルは、2 つの vmdk ファイルの機能を含む xml です。ファイルの内容は次のとおりです。

<ovf:VirtualSystem ovf:id="VMDK1">

                    <ovf:Item>
                    <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
                    <rasd:Description>Number of Virtual CPUs</rasd:Description>
                    <rasd:ElementName>8 virtual CPU(s)</rasd:ElementName>
                    <rasd:InstanceID>6</rasd:InstanceID>
                    <rasd:Reservation>9000</rasd:Reservation>
                    <rasd:ResourceType>3</rasd:ResourceType>
                    <rasd:VirtualQuantity>8</rasd:VirtualQuantity>
                    <rasd:Weight>8000</rasd:Weight>
                    <vmw:CoresPerSocket ovf:required="false">8</vmw:CoresPerSocket>
                </ovf:Item>
                <ovf:Item>
                    <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
                    <rasd:Description>Memory Size</rasd:Description>
                    <rasd:ElementName>12288 MB of memory</rasd:ElementName>
                    <rasd:InstanceID>7</rasd:InstanceID>
                    <rasd:Reservation>12288</rasd:Reservation>
                    <rasd:ResourceType>4</rasd:ResourceType>
                    <rasd:VirtualQuantity>12288</rasd:VirtualQuantity>
                    <rasd:Weight>122880</rasd:Weight>
                </ovf:Item>
</ovf:VirtualSystem>
<ovf:VirtualSystem ovf:id="VMDK2">

                    <ovf:Item>
                    <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
                    <rasd:Description>Number of Virtual CPUs</rasd:Description>
                    <rasd:ElementName>14 virtual CPU(s)</rasd:ElementName>
                    <rasd:InstanceID>7</rasd:InstanceID>
                    <rasd:Reservation>9000</rasd:Reservation>
                    <rasd:ResourceType>3</rasd:ResourceType>
                    <rasd:VirtualQuantity>14</rasd:VirtualQuantity>
                    <rasd:Weight>14000</rasd:Weight>
                    <vmw:CoresPerSocket ovf:required="false">14</vmw:CoresPerSocket>
                </ovf:Item>
                <ovf:Item>
                    <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
                    <rasd:Description>Memory Size</rasd:Description>
                    <rasd:ElementName>15360 MB of memory</rasd:ElementName>
                    <rasd:InstanceID>8</rasd:InstanceID>
                    <rasd:Reservation>15360</rasd:Reservation>
                    <rasd:ResourceType>4</rasd:ResourceType>
                    <rasd:VirtualQuantity>15360</rasd:VirtualQuantity>
                    <rasd:Weight>153600</rasd:Weight>
                </ovf:Item>

</ovf:VirtualSystem>

sedを使用してVMDK2の次のCPU構成のみを変更したいと思います。

<rasd:ElementName>14 virtual CPU(s)</rasd:ElementName>
<rasd:VirtualQuantity>14</rasd:VirtualQuantity>
<vmw:CoresPerSocket ovf:required="false">14</vmw:CoresPerSocket>

VirtualQuantity要素も含むVMDK2のメモリ構成を変更したくありません。

以下で試しましたが、VMDK1とVMDK2のCPU構成の両方が修正されました。

sed -i "/hertz/,/CoresPerSocket/s/[0-9]\+ virtual CPU/$cores virtual CPU/
/hertz/,/CoresPerSocket/s%<rasd:VirtualQuantity>[0-9]\+</rasd:VirtualQuantity>%<rasd:VirtualQuantity>$cores</rasd:VirtualQuantity>%
/CoresPerSocket/s/[0-9]\+/${cores}/" $ovf

ベストアンサー1

XMLを理解するXMLパーサーを使用してこれを正しく実行する方法は次のとおりです。

ncpus=16
xmlstarlet edit \
    -N xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" \
    -N xmlns:vcloud="http://www.vmware.com/vcloud/v1.5" \
    -N xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" \
    -N xmlns:vmw="http://www.vmware.com/schema/ovf" \
    --var vi '//ovf:VirtualSystem[@ovf:id="VMDK2"]/ovf:Item[rasd:Description="Number of Virtual CPUs"]' \
    --update '$vi/rasd:ElementName' --value "$ncpus virtual CPU(s)" \
    --update '$vi/rasd:VirtualQuantity' --value "$ncpus" \
    --update '$vi/vmw:CoresPerSocket' --value "$ncpus" \
    ova.ovf

<ovf:VirtualSystem id="VMDK2"/>これによりチャンクが選択され、<ovf:Item/>含まれているサブセクションが選択されます<rasd:Description>Number of Virtual CPUs</>。次に、$ncpusCPUの数をシェル変数の値(例では16)に置き換えます。これらのパラメータは、XMLデータを正しく解析する-N {namespace}ために必要です。xmlstarlet(単純な単一名前空間の場合、通常はデフォルト_名を使用できますが、ここではさまざまな要素の名前空間を明示的に識別する必要があります。)

正当なXMLファイルにするのに十分なXMLを含むように元の例を変更する必要がありました。

<Item xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
   xmlns:vcloud="http://www.vmware.com/vcloud/v1.5"
   xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
   xmlns:vmw="http://www.vmware.com/schema/ovf"
>
<ovf:VirtualSystem ovf:id="VMDK1">

…your examples here…

</ovf:VirtualSystem>
</Item>

多くのツールと同様に、このコマンドは編集された出力を次のように生成します。標準出力。あなたはそれを使用することができます所定の位置に本当に欲しいならマークしてください。ただし、テストするときはそうではありません。しかし、私がいつも好むのは、ファイルをバックアップとして保存し、編集した結果を元の名前に書き込むことです。このアプローチはすべてのツールで機能し、元のバージョンにあった可能性があるハードリンク、権限、およびその他のメタデータをそのまま残します。

xmlstarlet ... "original_file" >"original_file.$$.tmp" &&
    cp -fp "original_file" "backup_file" &&
    cat "original_file.$$.tmp" >"original_file"
rm -f "original_file.$$.tmp"

(ハードリンクとメタデータに興味がない場合は、それを単純化して置き換えることcatができますmv -f。)

おすすめ記事