유닉스 검색 및 바꾸기의 시작점을 지정한 다음 증분합니다.

유닉스 검색 및 바꾸기의 시작점을 지정한 다음 증분합니다.

XML 파일에서 참조된 속성의 번호를 다시 매기고 있습니다. 이 속성은 예를 들어 입니다 data-seq="1". 다음을 사용하여 모든 파일의 속성 번호를 다시 매길 수 있었습니다.

find $DATA_PATH/content/*.xml -exec perl -pi -e 's/data-seq="[0-9]+(?=")/qq(data-seq=").++$n/ge' {} +

이것은 훌륭하게 작동합니다. 하지만 저는 출발점을 추가하고 싶습니다. 예를 들어 data-seq="125"에서 번호 다시 매기기를 시작하고 거기에서 위로 올라갑니다. 그게 가능합니까?

다음은 몇 가지 예제 xml입니다(관련 속성과 기타 태그를 보여주는 작은 조각).

<b>Reconciliation</b>
<p>As often happens, just as one is beginning to find a solution <span class="page" title="20" data-seq="34"/>to a particular problem the problem becomes less pressing or ceases to exist.</p>
<span class="page" title="21" data-seq="35"/>
<b>The Multi-Plant Enterprise</b>
<p>The MNE is...

내가 원하는 것은 125 이전의 모든 것을 무시하고 data-seq="125"가 발견되면 모든 파일에서 126부터 번호를 다시 매기기 시작하는 것입니다. 이는 속성(연속되어야 함)에 간격이나 반복이 있어서 간격이나 반복 뒤의 다른 모든 숫자가 삭제되는 문제를 해결하기 위한 것입니다.

마크의 구조적 무결성 등을 확인할 필요가 없으며 숫자만 늘리면 됩니다.

그건 그렇고, 이것은 UNIX 텍스트 파일입니다.

감사해요.

답변1

일부 XML 예제가 없으면 이는 어렵습니다. 정규식은 실제로 XML을 잘 처리하지 못하므로 정규식을 사용하지 않는 것이 좋습니다.

나는 이렇게 할 수 있습니다 :

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig; 

my $start_renumber = 125;

my $twig = XML::Twig -> new ( pretty_print => 'indented_a' ) -> parse ( \*DATA ); 
foreach my $test_elt ( $twig -> findnodes ( '//test[@data-seq]' ) ) {
     $test_elt -> set_att('data-seq', $start_renumber++ );
}
$twig -> print; 

__DATA__
<xml>
   <test data-seq="999" />
   <test some-other="fish" />
   <test data-seq="123125" />
</xml>

출력을 다음으로 변경합니다.

<xml>
  <test data-seq="125" />
  <test some-other="fish" />
  <test data-seq="126" />
</xml>

File::Find그리고 이를 원하는 모든 파일 과 결합하세요 .

이 같은:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;
use File::Find;

my $start_renumber = 125;

sub update_data_seq {
    my ( $twig, $element ) = @_;
    if ( $element -> att('data-seq') > 125 ) { 
        $element->set_att( 'data-seq', $start_renumber++ );
    }
}

sub process_xml {
    next unless -f;
    next unless m/\.xml/;
    my $twig = XML::Twig->new(
        pretty_print  => 'indented_a',
        twig_handlers => { '//span[@data-seq]' => \&update_data_seq }
    );
    $twig->parsefile_inplace($File::Find::name);

}

find( \&process_xml, "/path/to/search/for/xml",
    "/some/other/path/if/you/want" );

관련 정보