XML 파일 편집 - 문자열을 찾은 다음 텍스트 블록을 삭제하고/문자열을 찾은 다음 새 텍스트 블록을 삽입합니다.

XML 파일 편집 - 문자열을 찾은 다음 텍스트 블록을 삭제하고/문자열을 찾은 다음 새 텍스트 블록을 삽입합니다.

모두 안녕하십니까,

저는 UNIX를 처음 접했기 때문에 VB에서 할 수 있는 일을 하고 싶었지만 UNIX에서는 해본 경험이 없습니다.

새로운 Reuters RIC 코드가 온라인에 나올 때 정기적으로 제거하고 업데이트해야 하는 공유 XML 사양이 있습니다. 구현할 두 가지 프로젝트:

A. RIC 항목 삭제

  1. 파일을 열다
  2. 특정 문자열 찾기
  3. 찾은 줄과 그 아래 21줄을 삭제합니다.
  4. 아카이브 저장

내 생각엔 이것이 효과가 있을 것 같다:

sed –e '/<ric id="AUG03250639E=YBAU">/,+21d'  a.xml >a.xml

B. 새로운 RIC 항목 추가

  1. 파일을 열다
  2. 마지막으로 발생한 sting 찾기</source>
  3. 마지막 RIC 입력 블록까지 29줄 위로 이동
  4. 이 줄과 아래 21줄을 복사하세요(ric 블록).
  5. 22번 줄 아래에 새 줄을 삽입하고 이 블록(새 블록)을 복사한 블록 바로 아래에 붙여넣습니다.
  6. 새 블록의 라인 1에 있는 ric을 새 Ric 문자열로 변경합니다 <ricid="AAAAA=YBAU".<ricid="BBBBB=YBAU"
  7. 아카이브 저장

어떻게 해야 하나요?

파일의 마지막 부분입니다. (내가 조작하고 싶은) ric 블록의 끝은 다음 문자열이 나타날 때입니다. . .

            <ric id="AUG03250639E=YBAU">
                <securities>
                    <security>
                        <issueid>178117</issueid>
                        <quote-type>YIELD</quote-type>
                        <complex-logic>
                            <calculations>
                                <yield-type>
                                    <type>BID_YIELD</type>
                                    <calculation name="AB" field="RT_YIELD_1" />
                                </yield-type>
                                <yield-type>
                                    <type>OFFER_YIELD</type>
                                    <calculation name="AB" field="SEC_YLD_1" />
                                </yield-type>
                            </calculations>
                        </complex-logic>
                        <derived-type name="PRICE" baseValue="100.0" />
                    </security>
                </securities>
            </ric>
            <ric id="AUG03250640E=YBAU">
                <securities>
                    <security>
                        <issueid>178117</issueid>
                        <quote-type>YIELD</quote-type>
                        <complex-logic>
                            <calculations>
                                <yield-type>
                                    <type>BID_YIELD</type>
                                    <calculation name="AB" field="RT_YIELD_1" />
                                </yield-type>
                                <yield-type>
                                    <type>OFFER_YIELD</type>
                                    <calculation name="AB" field="SEC_YLD_1" />
                                </yield-type>
                            </calculations>
                        </complex-logic>
                        <derived-type name="PRICE" baseValue="100.0" />
                    </security>
                </securities>
            </ric>
        </rics>
        <topics>
            <topic>
                <id>default</id>
                <type>rmds</type>
                <value>IDN_SELECTFEED.ANY.%s.NaE</value>
            </topic>
        </topics>
    </source>

    <transformers>
        <!-- Name of transformer -->
        <transformer></transformer>
    </transformers>

    <processors>
        <!-- Enricher to add additional fields from source query result while 
            publishing -->
        <processor></processor>
    </processors>
    <endpoints>
        <!-- Order of post processor is important. First topic, then mapper -->

        <endpoint id="rmds" topic="FI.ANY.%s.YBAU" multicast="true">

            <postprocessor>reuters-topic-builder</postprocessor>
            <postprocessor>reuters-message-mapper</postprocessor>
            <!-- <multitopic id="solace" topic="LN/FI/IP/APS/SSHEET/YIELD/BATS_%s" 
                /> -->
            <multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/SSHEET/BATS_%s" />
            <multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/YIELDBROKER/BATS_%s" />
        </endpoint>

    </endpoints>
    <other-properties>
        <!-- common formatting of price/yield -->
        <property name="formattor-1">(math:pow(INPUT/100+1,0.5)-1)*200</property>
        <property name="handle_negative_values">false</property>
        <property name="handle_negative_values_output">0.001</property>
    </other-properties>
</specification>

따라서 A. AUG03250640E=YBAU를 삭제하려는 RIC 항목을 삭제하면 파일에 다음이 표시됩니다.

            <ric id="AUG03250639E=YBAU">
                <securities>
                    <security>
                        <issueid>178117</issueid>
                        <quote-type>YIELD</quote-type>
                        <complex-logic>
                            <calculations>
                                <yield-type>
                                    <type>BID_YIELD</type>
                                    <calculation name="AB" field="RT_YIELD_1" />
                                </yield-type>
                                <yield-type>
                                    <type>OFFER_YIELD</type>
                                    <calculation name="AB" field="SEC_YLD_1" />
                                </yield-type>
                            </calculations>
                        </complex-logic>
                        <derived-type name="PRICE" baseValue="100.0" />
                    </security>
                </securities>
            </ric>
        </rics>
        <topics>
            <topic>
                <id>default</id>
                <type>rmds</type>
                <value>IDN_SELECTFEED.ANY.%s.NaE</value>
            </topic>
        </topics>
    </source>

    <transformers>
        <!-- Name of transformer -->
        <transformer></transformer>
    </transformers>

    <processors>
        <!-- Enricher to add additional fields from source query result while 
            publishing -->
        <processor></processor>
    </processors>
    <endpoints>
        <!-- Order of post processor is important. First topic, then mapper -->

        <endpoint id="rmds" topic="FI.ANY.%s.YBAU" multicast="true">

            <postprocessor>reuters-topic-builder</postprocessor>
            <postprocessor>reuters-message-mapper</postprocessor>
            <!-- <multitopic id="solace" topic="LN/FI/IP/APS/SSHEET/YIELD/BATS_%s" 
                /> -->
            <multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/SSHEET/BATS_%s" />
            <multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/YIELDBROKER/BATS_%s" />
        </endpoint>

    </endpoints>
    <other-properties>
        <!-- common formatting of price/yield -->
        <property name="formattor-1">(math:pow(INPUT/100+1,0.5)-1)*200</property>
        <property name="handle_negative_values">false</property>
        <property name="handle_negative_values_output">0.001</property>
    </other-properties>
</specification>

B. 새 RIC 항목 추가의 경우 새 ric AUG03250641E=YBAU를 추가한다고 가정하면 파일에 다음이 표시됩니다.

            <ric id="AUG03250639E=YBAU">
                <securities>
                    <security>
                        <issueid>178117</issueid>
                        <quote-type>YIELD</quote-type>
                        <complex-logic>
                            <calculations>
                                <yield-type>
                                    <type>BID_YIELD</type>
                                    <calculation name="AB" field="RT_YIELD_1" />
                                </yield-type>
                                <yield-type>
                                    <type>OFFER_YIELD</type>
                                    <calculation name="AB" field="SEC_YLD_1" />
                                </yield-type>
                            </calculations>
                        </complex-logic>
                        <derived-type name="PRICE" baseValue="100.0" />
                    </security>
                </securities>
            </ric>
            <ric id="AUG03250640E=YBAU">
                <securities>
                    <security>
                        <issueid>178117</issueid>
                        <quote-type>YIELD</quote-type>
                        <complex-logic>
                            <calculations>
                                <yield-type>
                                    <type>BID_YIELD</type>
                                    <calculation name="AB" field="RT_YIELD_1" />
                                </yield-type>
                                <yield-type>
                                    <type>OFFER_YIELD</type>
                                    <calculation name="AB" field="SEC_YLD_1" />
                                </yield-type>
                            </calculations>
                        </complex-logic>
                        <derived-type name="PRICE" baseValue="100.0" />
                    </security>
                </securities>
            </ric>
            <ric id="AUG03250641E=YBAU">
                <securities>
                    <security>
                        <issueid>178117</issueid>
                        <quote-type>YIELD</quote-type>
                        <complex-logic>
                            <calculations>
                                <yield-type>
                                    <type>BID_YIELD</type>
                                    <calculation name="AB" field="RT_YIELD_1" />
                                </yield-type>
                                <yield-type>
                                    <type>OFFER_YIELD</type>
                                    <calculation name="AB" field="SEC_YLD_1" />
                                </yield-type>
                            </calculations>
                        </complex-logic>
                        <derived-type name="PRICE" baseValue="100.0" />
                    </security>
                </securities>
            </ric>
        </rics>
        <topics>
            <topic>
                <id>default</id>
                <type>rmds</type>
                <value>IDN_SELECTFEED.ANY.%s.NaE</value>
            </topic>
        </topics>
    </source>

    <transformers>
        <!-- Name of transformer -->
        <transformer></transformer>
    </transformers>

    <processors>
        <!-- Enricher to add additional fields from source query result while 
            publishing -->
        <processor></processor>
    </processors>
    <endpoints>
        <!-- Order of post processor is important. First topic, then mapper -->

        <endpoint id="rmds" topic="FI.ANY.%s.YBAU" multicast="true">

            <postprocessor>reuters-topic-builder</postprocessor>
            <postprocessor>reuters-message-mapper</postprocessor>
            <!-- <multitopic id="solace" topic="LN/FI/IP/APS/SSHEET/YIELD/BATS_%s" 
                /> -->
            <multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/SSHEET/BATS_%s" />
            <multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/YIELDBROKER/BATS_%s" />
        </endpoint>

    </endpoints>
    <other-properties>
        <!-- common formatting of price/yield -->
        <property name="formattor-1">(math:pow(INPUT/100+1,0.5)-1)*200</property>
        <property name="handle_negative_values">false</property>
        <property name="handle_negative_values_output">0.001</property>
    </other-properties>
</specification>

답변1

~을 위한POSIX sedhead유틸리티는 물론 일반in문서:

{   sed  -ne'/^<ric id="AUG03250639E=YBAU">$/q;p'
    head -n21 >/dev/null
    cat
}   <in >out

답변2

구문 분석 및/또는 조작이라는 사실 외에도정규 표현식이 포함된 xml기껏해야 오해의 소지가 있지만(조심하면 이렇게 간단한 것도 효과가 있을 수 있지만) 거의 옳습니다.

GNU sed 사용:

sed –i -e '/<ric id="AUG03250639E=YBAU">/,+21d'  a.xml

-ised가 ( ) 옵션을 지원하지 않는 경우 --in-place임시 파일을 사용하여 이 작업을 수행할 수 있습니다(sed가 뒤에서 작동하는 방식입니다).

TF=$(mktemp)
sed -e '/<ric id="AUG03250639E=YBAU">/,+21d'  a.xml > "$TF" && mv "$TF" a.xml

시도하는 것처럼 셸에서 파일을 읽고 출력을 해당 파일로 리디렉션할 수 없습니다. 셸이 가장 먼저 하는 일은 파일을 덮어써서 비워 만드는 것인데, 이는 sed 스크립트가 실행되기 전에 발생합니다.

보다 복잡한 XML 구문 분석 작업의 경우 쉘 스크립트의 XML 구문 분석기를 사용 xmlstarlet하거나 Perl 또는 Python(또는 생각할 수 있는 거의 모든 언어)용 XML 구문 분석 라이브러리 중 하나를 사용하세요.

답변3

XML을 구문 분석하는 데 정규식을 사용하지 마세요. 더럽습니다. 쉽게 깨지고 부서지기 쉬운 코드를 생성합니다. 줄 수와 같이 문제를 일으킬 수 있는 많은 것들이 있습니다. 요소의 형식을 XML로 지정하는 것은 완벽하게 유효합니다.

<calculation name="AB" field="SEC_YLD_1" />

또는:

<calculation
    field="SEC_YLD_1"
    name="AB"
/>

및 기타 다양한 옵션 - 모두 의미상 동일하지만... 동일한 정규식과 일치하지 않습니다.

예를 들어 파서를 사용하면 매우 간단합니다. 이 작업을 쉽게 수행할 수 있는 방법이 perl있습니까 ?XML::Twig

삭제:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $twig = XML::Twig -> parsefile ( 'your_file.xml' );

$_ -> delete for $twig -> get_xpath('//ric[@id="AUG03250639E=YBAU"]');

$twig -> set_pretty_print('indented');
$twig -> print;

참고 - 중복된 항목이 있으면 제거하세요.

이제 새 항목을 만듭니다. 복사하고 수정하려는 것 같습니다. 따라서:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $twig = XML::Twig -> parsefile ( 'your_file.xml' );

#find one to copy - this will just get the first 'ric' element. 
my $ric_to_copy = $twig -> get_xpath('//ric',0); 
#copy it
my $new_ric = $ric_to_copy -> copy;
#alter the new one
$new_ric -> set_att('id', 'BBBBB=YBAU' );
#paste it
$new_ric -> paste ( 'last_child', $ric_to_copy->parent);
$twig -> set_pretty_print('indented');
$twig -> print;

이제 STDOUT을 읽고 인쇄합니다. 특정 파일로 인쇄할 수 있습니다.

my ( $output, '>', 'new.xml') or die $!;
print {$output} $twig -> sprint;
close ( $output );

관련 정보