Perl如何在关键字match前面引入文本并保留文件中的其余内容

问题描述

我是perl的新手,我需要在找到关键字(匹配项)后通过添加一些文本来编辑文本文件,我需要将更改保存在同一文件中,但保留所有旧信息,而不覆盖任何内容

即使文件中的其他数据发生变化,关键字(匹配)和我要添加的信息也会保持不变。

To make a summary:

data that will change (not interested)

...

empty spaces < DATA >B506JGHD (< DATA > it would be the keyword(match) and i want to add for example 00000001 after it)

output that I need:empty spaces< DATA >00000001B506JGHD

...

empty spaces< DATA >J6443MNF

output:empty spaces< DATA >00000002J6443MNF

...


empty spaces< DATA >C89583F

output:empty spaces< DATA >00000003C89583F

...
other data (not interested)  

依此类推,这就像文件中的7 ,所以我想为每个添加00000000到00000006。

我正在寻找一个简单的解决方案(如果存在),我知道我可能需要阅读并遍历文本文件,找到关键字并重写所有内容,但是我不确定如何做到这一点。

What I tried so far is this:

use strict;
use warnings;

open FILE,"<FL_85E920795_Y060_H21_V001_E.odx" or die $!;
my @lines = < FILE >;
close FILE or die $!;

my $idx = 0;
my $string = '00000000';
do {
    if($lines[$idx] =~ /< DATA >/) 
        {
            splice @lines,$idx,$string++;
            $idx++;
        }
    $idx++;
    } until($idx >= @lines);

open FILE,">FL_85E920795_Y060_H21_V001_E.odx" or die $!;
print FILE join("",@lines);
close FILE;

但是对我没有太大帮助,因为我的输出是这样的: 00000000空格信息,如果我尝试将所需的数据移到之前,它将覆盖所有内容

我将接受第一个我有用的答复作为解决方案。 非常感谢

解决方法

#!/usr/bin/perl

use strict;
use warnings;

my $counter = "00000000";
while (<>) {
   s{< DATA >\K}{ $counter++ }eg;
   print;
}

用法:

fn=FL_85E920795_Y060_H21_V001_E.odx
the_script "$fn" >"$fn".new
mv "$fn".new "$fn"

\K“保留”与\K匹配的内容,因此仅将< DATA >之后的空字符串替换为替换表达式返回的值。


“单线”:

perl -i -pe'BEGIN { $c = "00000000" }  s{< DATA >\K}{ $c++ }eg' \
   FL_85E920795_Y060_H21_V001_E.odx
,

所需的结果可以通过以下演示代码来实现

注意:

  • 此解决方案将整个文件读取到内存中
  • 如果文件太大,最好逐行读取方法
use strict;
use warnings;
use feature 'say';

my $count = 0;
my $re_match = qr/< DATA >/;

my $data = do { local $/; <DATA> };

$data =~ s/$re_match/sprintf "%08d",$count++/ge;

say $data;

__DATA__
To make a summary:

data that will change (not interested)

...

empty spaces < DATA >B506JGHD (< DATA > it would be the keyword(match) and i want to add for example 00000001 after it)

output that I need:empty spaces< DATA >00000001B506JGHD

...

empty spaces< DATA >J6443MNF

output:empty spaces< DATA >00000002J6443MNF

...


empty spaces< DATA >C89583F

output:empty spaces< DATA >00000003C89583F

...
other data (not interested) 

输出

To make a summary:

data that will change (not interested)

...

empty spaces 00000000B506JGHD (00000001 it would be the keyword(match) and i want to add for example 00000001 after it)

output that I need:empty spaces0000000200000001B506JGHD

...

empty spaces00000003J6443MNF

output:empty spaces0000000400000002J6443MNF

...


empty spaces00000005C89583F

output:empty spaces0000000600000003C89583F

...
other data (not interested)