Perl如何在关键字(匹配)前面引入文本并将其余部分保留在文件中

Perl how to introduce a text in front of a keyword(match) and keep the rest from a file

我是 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 < DATA > 所以我想为每个 < DATA > 添加 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, 0, $string++;
            $idx++;
        }
    $idx++;
    } until($idx >= @lines);

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

但对我帮助不大,因为我的输出是这样的: 00000000 个空格 < DATA > 信息,如果我尝试将我想要的数据移动到 < DATA > 前面,它会覆盖所有内容。

我会接受对我有用的第一个响应作为解决方案。 非常感谢

#!/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 > 后面的空字符串替换为替换表达式返回的值。


作为“one-liner”:

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)