XML 文書の値を、文書の他の場所から取得した別の値に置き換えます。

XML 文書の値を、文書の他の場所から取得した別の値に置き換えます。

スクリプト:

#!/bin/ksh

tu=$(cat /export/home/a1016169/stack.txt;)
tu1=$(echo "$tu" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/tu/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
print "\n $tu1"

qc=$(cat /export/home/a1016169/stack.txt;)
qc1=$(echo "$qc" | awk '/EM_CLIENT_VERSION/{x=NR+17}(NR<=x){print}' | awk '/qc/{x=NR+1}(NR<=x){getline; print}' | awk -F= '{print $(NR+2)}' | perl -lne 'print substr($_,19,5)';)
print "\n $qc1"

sed 's/"$qc1"/"$tu1"/' - > /export/home/a1016169/stack.txt

stack.txt文書:

 <prpr name = "EM_CLIENT_VERSION" encryptionClass = "com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
                <lcycl name="pu">
                        <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
                </lcycl>
                <lcycl name="qc">
                        <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
                </lcycl>
                <lcycl name="qa">
                        <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
                </lcycl>
                <lcycl name="tu">
                        <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
                </lcycl>
                <lcycl name="dv">
                        <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"></prprvl>
                </lcycl>
            </prpr>

最後のコマンドでエラーが発生しましたCan't open -

9999a<lcycl name="qc">このセクションでのみ)0220a値を変更したいと思います。値はから取得する必要があります<lcycl name="tu">

ベストアンサー1

使用XMLスター:

$ xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' -v 0220a file.xml
<?xml version="1.0"?>
<prpr name="EM_CLIENT_VERSION" encryptionClass="com.hewitt.cat.tba.properties.encrypter.NoOpPropertyEncrypter">
  <lcycl name="pu">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999a</prprvl>
  </lcycl>
  <lcycl name="qc">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
  </lcycl>
  <lcycl name="qa">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">9999b</prprvl>
  </lcycl>
  <lcycl name="tu">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00">0220a</prprvl>
  </lcycl>
  <lcycl name="dv">
    <prprvl bgdt="2000.01.01 00:00" endt="3000.01.01 00:00"/>
  </lcycl>
</prpr>

XPathは、//lcycl[@name="qc"]/prprvl値属性を持つノードprprvlの直系の子ノードと一致します。ここでは、ノードの初期値が何であれ、その値が変更されます。lcyclnameqcxmlstarletprprvl0220a

値をハードコーディング0220aせずにノードで選択するには、次のように//lcycl[@name="tu"]/prprvlします。

xmlstarlet ed -u '//lcycl[@name="qc"]/prprvl' \
              -x '//lcycl[@name="tu"]/prprvl/text()' file.xml

出力を新しいファイルにリダイレクトし、新しいファイルの名前を元の名前に変更します。


file.xmlPerlの対応するエントリは現在のディレクトリから取得されます。

#!/usr/bin/perl

use strict;
use warnings;

use XML::XPath;
use XML::XPath::XMLParser;

my $xp = XML::XPath->new( filename => 'file.xml' );

$xp->setNodeText( '//lcycl[@name="qc"]/prprvl', '0220a' );

my $nodeset = $xp->find('/');

foreach my $node ( $nodeset->get_nodelist() ) {
    print XML::XPath::XMLParser::as_string($node);
}

ここで別のノードから値を選択するには、次を使用します。

$xp->setNodeText( '//lcycl[@name="qc"]/prprvl',
    $xp->getNodeText('//lcycl[@name="tu"]/prprvl') );

setNodeText()他のラインよりも

出力を新しいファイルにリダイレクトし、新しいファイルの名前を元の名前に変更します。


-GNUはsedこれを標準入力ストリームとして扱います-が、他のsed実装(BSDなどsed)ではそれを一般的なファイル名として扱います。

いかなる場合においても、お客様はsed実行可能なデータを提供しません。これは、リダイレクトするファイルが切り捨てられ、空であることを意味します。

おすすめ記事