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실행 가능한 데이터를 제공하지 않습니다. 이는 리디렉션하는 파일이 잘리고 비어 있음을 의미합니다.

관련 정보