读取文件并进行修改

问题描述 投票:2回答:4

我正在尝试处理数据流。

首先,我将一个文本文件添加到我的脚本中。

文本文件如下:

pierwsza linia  koniec
druga linia lorem1 koniec lorem1 lorem1
trzecia linia lorem1 koniec lorem1
czwarta linia lorem1 koniec
piata liniakoniec
szosta linia lorem1 koniec

我想要实现的是一个包含所有行的文件,但只有第一次出现的lorem1

所以预期的结果应该是这样的

pierwsza linia  koniec
druga linia lorem1 koniec
trzecia linia koniec
czwarta linia koniec
piata liniakoniec
szosta linia koniec

我的脚本是这样的

#!/usr/bin/perl -pi

use strict;

my $line = $_;
my $loremcn;

while ( $line = <> ) {

    #if ( $line =~ m/lorem1/ )

    foreach ( $line =~ m/lorem1/gi ) {

        $loremcn++;

        if ( $loremcn >= 2 ) {
            $line =~ s/lorem1//gi;
        }

        print "$loremcn\n";
        print $line;

        chomp $line;
    }
}

然而,结果只是一行,第一行(因为脚本开头的-pi)的文本。

该脚本正确计算lorem1(7)的出现次数,但由于/g选项,它删除所有lorem1事件(它不会留下第一个单独)。

最后,如何将整个修正后的文本打印到屏幕上?

Update

我在其中一个答案上写了这个重要的评论:

在RL我不能这样做。这整个练习是为了找到一种如何使用流数据执行此操作的方法。在真实场景中,整个数据不是来自打开的文本,而是从SAP流式传输到打印机的假脱机数据。并且该数据需要在去往打印机的途中得到纠正

regex perl aix
4个回答
2
投票
#!/usr/bin/perl 
use strict;
use warnings;

# lorem counter
my $loremcn = 0;
# loop over the input file
while (my $line = <> ) {
    # if line contains lorem1 but not alorem1 or lorem12
    if ($line =~ /\blorem1\b/i) {
        # not the first time. counter > 0
        if ($loremcn) {
            # remove all lorem1 and optional leading horizontal spaces
            $line =~ s/\h*\blorem1\b//gi;   # comment for syntax color /
        # first time lorem1 is encountered (counter == 0)
        } else {
            # remove all lorem1 but the first
        while ($line =~ s/
                            (\blorem1\b.*?)     # first lorem1 in the line followed by 0 or more anycharacter
                            \blorem1\b          # subsequent lorem1
                            /$1/gix             # replace with the first group (i.e. the first lorem1
            ) { 1;}
        }
        # incement counter
        $loremcn++;
    }
    # print the modified line
    print $line;
}

输出:

pierwsza linia  koniec
druga linia lorem1 koniec  
trzecia linia koniec
czwarta linia koniec
piata liniakoniec
szosta linia koniec

用法:

perl test.pl inputfile > outputfile

1
投票

使用perl的一个班轮:

您可以保留所有内容,直到第一个lorem然后删除所有的lorems,即

 $perl -pe "undef $/;s/^.*?\blorem1\K|\blorem1//g" lorem.txt
  • \b-用于确定边界。
  • .*?-非贪婪的比赛。将一切都与第二个lorem相匹配
  • \K - 丢弃任何以前消费的角色。从而从第二个lorem删除到结尾

产量

pierwsza linia  koniec
druga linia lorem1 koniec
trzecia linia  koniec
czwarta linia  koniec
piata liniakoniec
szosta linia  koniec

现在,如果要将其保存在另一个文件中,您可以执行以下操作:

perl -pe "undef $/;s/^.*?\blorem1\K|\blorem1//g" lorem.txt > new_file.txt

如果您的perl版本不支持\K,您可以使用:

 perl -pe "undef $/;s/(^.*?\blorem1)|\blorem1/$1/g" lorem.txt

0
投票

不就是这个吗?

my $seen;
while (<>) {
  s/\blorem1\b//g if $seen;
  $seen = 1 if /\blorem1\b/;
  print;
}

更新:好的,它比我原先想象的要复杂一点。但这似乎做你想要的:

#!/usr/bin/perl

use strict;
use warnings;

my $seen;

while (<>) {
  if ($seen) {
    s/\blorem1\b//g;
  } else {
    1 while s/(?<=\blorem1\b)(.*)\blorem1\b/$1/g;
    $seen = 1 if /\blorem1\b/;
  }
  print;
}

-1
投票

B::Deparse一样运行你的代码

perl -MO=Deparse xx.pl

给出了这个结果

BEGIN { $^I = ""; }   # From -i

LINE: while (defined($_ = readline ARGV)) {


    use strict;
    my $line = $_;
    my $loremcn;
    while (defined($line = readline ARGV)) {
        foreach $_ ($line =~ /lorem1/gi) {
            ++$loremcn;
            if ($loremcn >= 2) {
                $line =~ s/lorem1//gi;
            }
            print "$loremcn\n";
            print $line;
            chomp $line;
        }
    }


}
continue {
    die "-p destination: $!\n" unless print $_;
}

所以你看到你的代码中有两个while循环:你不应该将命令行选项与程序文件混淆,因为结果可能不明显

这是一种做我认为你想要的方法。它使用你的全局计数器$loremcn和一个表达式全局替换来在第一个实例之后没有任何内容替换lorem1

#!/usr/bin/perl

use strict;
use warnings 'all';

@ARGV = 'file1.txt';

my $loremcn = 0;

while ( <> ) {

    s{(\blorem1\b[ \t]*)}{ $loremcn++ ? '' : $1 }ge;

    print;
}

output

pierwsza linia  koniec
druga linia lorem1 koniec 
trzecia linia koniec 
czwarta linia koniec
piata liniakoniec
szosta linia koniec
© www.soinside.com 2019 - 2024. All rights reserved.