如何使用backreferrence匹配简单的数学运算?

时间:2016-11-23 08:42:18

标签: regex perl awk sed

我有一个文件如下:

~ cat dump.txt
  <ItemSpec id="46301" Day="1" Week="244251"/>
  <ItemSpec id="46302" Day="2" Week="244252"/>
  <ItemSpec id="46303" Day="3" Week="244253"/>
  <ItemSpec id="46304" Day="4" Week="244254"/>
  <ItemSpec id="46305" Day="5" Week="244255|244256|244257|244255|244256|244257|244255|244256|244257|244255|244256|244257"/>
  ...

我希望Week列号在处理后添加100,000,就像:

~ <simple shell code> dump.txt
  <ItemSpec id="46301" Day="1" Week="344251"/>
  <ItemSpec id="46302" Day="2" Week="344252"/>
  <ItemSpec id="46303" Day="3" Week="344253"/>
  <ItemSpec id="46304" Day="4" Week="344254"/>
  <ItemSpec id="46305" Day="5" Week="344255|344256|344257|344255|344256|344257|344255|344256|344257|344255|344256|344257"/>
  ...

我不知道是否有一种简单的方法可以将反向引用作为数学运算的数字。我的无助尝试如下:

~ awk '{print gensub(/([0-9]{6})/,"\\1+100000","g",$0)}' dump.txt
  <ItemSpec id="46301" Day="1" Week="244251+100000"/>
  <ItemSpec id="46302" Day="2" Week="244252+100000"/>
  <ItemSpec id="46303" Day="3" Week="244253+100000"/>
  <ItemSpec id="46304" Day="4" Week="244254+100000"/>
  <ItemSpec id="46305" Day="5" Week="244255+100000|244256+100000|244257+100000|244255+100000|244256+100000|244257+100000|244255+100000|244256+100000|244257+100000|244255+100000|244256+100000|244257+100000"/>


  ...

任何想法都会有所帮助,谢谢!

3 个答案:

答案 0 :(得分:2)

这看起来像XML。 P arsing XML as plain text is a bad idea - 正则表达式适用于常规语言,而XML则不适用。

所以解析为XML:

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

use XML::Twig;

sub increment_week {
   my ( $twig, $itemspec ) = @_; 
   my @values = split /\|/, $itemspec -> att ('Week');
   $_ .= "+10000" for @values;
   $itemspec -> set_att('Week', (join '|', @values ));

}

my $twig = XML::Twig -> new ( keep_atts_order => 1,
                              pretty_print => 'indented',
                              twig_handlers => { 'ItemSpec' => \&increment_week } );
   $twig -> parsefile ('your_file.xml'); 
   $twig -> print;

这意味着您将以XML的形式处理整个事情,并且不会被有效的XML差异所绊倒(XML允许您在不改变语义的情况下包装行,更改属性排序等)。

当然,如果不是有效的XML,这将无法正常工作 - 但是像这样编写“几乎是XML”是一件非常肮脏的事情。 (几乎像肮脏的一样肮脏,以“修复”它)

答案 1 :(得分:0)

发现一个类似的问题和问题解决了!

Math operations in regex

perl -pe 's/(\d{6})/$1+100000/eg' dump.txt

答案 2 :(得分:0)

可能你可以试试这个:

my $line = $_; my $i = 100000;
$line=~s#\s+Week="([^"]*)"# my $weeks=$&; $weeks=~s/\b(\d+)\b/($1+$i)/ge; ($weeks);#esg;