指定unix查找和替换的起点,然后递增

指定unix查找和替换的起点,然后递增

我正在对 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" );

相关内容