Regex sed-使用特定位数更改模式

Regex sed-使用特定位数更改模式,regex,perl,Regex,Perl,我正在尝试对以下一组行执行替换: 1AA20160817BBBBBDIGITS1NUMBER1STYLE59 00002200000220 1AA20160817BBBBBDIGITS2NUMBER1STYLE60 00000000000220 1AA20160817DDDDDDIGITS3NUMBER2STYLE60 00000000000486 1AA20160817DDDDDDIGITS4NUMBER2STYLE59 00004860

我正在尝试对以下一组行执行替换:

1AA20160817BBBBBDIGITS1NUMBER1STYLE59        00002200000220
1AA20160817BBBBBDIGITS2NUMBER1STYLE60        00000000000220
1AA20160817DDDDDDIGITS3NUMBER2STYLE60        00000000000486
1AA20160817DDDDDDIGITS4NUMBER2STYLE59        00004860000486
1AA20160817FFFFFDIGITS5NUMBER3STYLE602523111100000000000000
1AA20160817FFFFFDIGITS6NUMBER3STYLE59        00000820000000
我希望最终输出如下:

1AA20160817BBBBBDIGITS1NUMBER1STYLE59        00002200000220
1AA20160817BBBBBDIGITS1NUMBER1STYLE60        00000000000220
1AA20160817DDDDDDIGITS3NUMBER2STYLE60        00000000000486
1AA20160817DDDDDDIGITS3NUMBER2STYLE59        00004860000486
1AA20160817FFFFFDIGITS5NUMBER3STYLE602523111100000000000000
1AA20160817FFFFFDIGITS5NUMBER3STYLE59        00000820000000
变化是一个数字,就在每第二行“数字”之前。BBBBB/DDDDD样式中的模式是时间,最后一个字符是秒指示器

我希望它检查特定数量的字符并在那里执行更改,我已经编写了sed来执行该任务,以及类似的任务:

sed -i.bak "s/^\(.\{1\}\)$scenario$datein\(.\{6\}\)$pod/1$scenario$datein$timein$pod/g" $1

代码的其余部分是Perl。你们中有人能帮我用Perl做同样的替换吗?或者告诉我如何从perl代码运行这个sed命令?我的问题是所讨论的文件很大,bash读取每一行并执行替换需要花费太长的时间。提前感谢。

通过查看
$可以识别偶数行和奇数行。
--从(上次访问的)文件句柄读取的当前行号。看到了

/e
修饰符首先对替换侧进行求值,然后将其结果用作替换。见和

如果位置固定,则可以使用

my $offset = length '1AA20160817BBBBBDIGITS';

while (<DATA>) 
{
    if ($. % 2 != 0) {
        # Retrieve substring of length 1 at given offset
        $set_num_to = substr $_, $offset, 1;
    }
    else {
        # Replace substring of same length at same offset by one captured above
        substr $_, $offset, 1, $set_num_to;
    }
}
my$offset=length'1AA20160817BBBBBBBDigits';
而()
{
如果($.%2!=0){
#在给定偏移量处检索长度为1的子字符串
$set_num_to=substr$\$offset,1;
}
否则{
#将相同偏移量下相同长度的子字符串替换为上面捕获的子字符串
substr$\uu$offset,1,$set\u num\u为;
}
}
其余部分相同,并按指定打印行


同样,如果您需要从中减去1,而不是用前一行中的数字替换,您可以在
$中使用上面两行2==0
条件。

假设您的输入数据位于
data.txt
中:

$ perl -i -pe's/(\d)(?=NUMBER)/$1-1/e if ! ($. % 2)' data.txt
  • -i
    :就地编辑输入文件并创建备份
  • -p
    :在输入中的每一行运行此代码,并在每次迭代中打印$
  • -e
    :要运行的代码
  • s/(\d)(?=NUMBER)/$1-1/e
    :查找后跟“NUMBER”的数字,并将其替换为从该数字中减去的数字
  • if!($。%2)
    :但仅对偶数记录执行此操作

第一块和第二块有什么区别?对我来说,它们看起来一样好,不仅仅是我…:)每一个块都有一个不同的字符,就在“数字”将其添加到主文本之前,这样就不会出现混淆。提供一个易于跟踪的字符总是好的。这里,
…CNUMBER…
…BNUMBER…
看起来非常相似。你能不能简化这个例子,让每个人都更容易回答并基本上理解你的最终目标?
my $offset = length '1AA20160817BBBBBDIGITS';

while (<DATA>) 
{
    if ($. % 2 != 0) {
        # Retrieve substring of length 1 at given offset
        $set_num_to = substr $_, $offset, 1;
    }
    else {
        # Replace substring of same length at same offset by one captured above
        substr $_, $offset, 1, $set_num_to;
    }
}
$ perl -i -pe's/(\d)(?=NUMBER)/$1-1/e if ! ($. % 2)' data.txt