我的文件input.dat
如下:
ZZZ 111
ABC 523
ABC 835
ADD 234
ZZZ 222
ABC 0007
2935
ABC 4
ABC 893
wdq
ZZZ 333
ABC 777
ABC 00
我能够在ABC
之后提取字符串,但我需要获得每个第n个外观。所以我无法单独区分正则表达式,并认为循环可以处理这个问题。为了获得ABC行上的每一秒条,我试过:
#!/usr/bin/perl
use strict;
use warnings;
my $i;
my @grepped
open(INFILE,"input.dat") or die "$! Exiting.\n";
while (my $line = <INFILE>) {
if ($line =~ /^ZZZ (\d+)/){
push(@grepped,"$1\t")
};
$i=0;
for ($line =~ /^ABC (\d+)/){
$i+=1;
if($i==2){ push(@grepped,"$1\n") };
};
}
close(INFILE);
循环不能正常工作,我不知道为什么。我得到了:
111 523
835
222 0007
4
333 777
00
而不是所需的:
111 835
222 4
333 00
答案 0 :(得分:3)
将一行与正则表达式匹配不会从输入文件中读取下一行。您必须以某种方式记住循环的每次迭代的状态,例如通过存储您在变量中看到ABC的次数。遇到ZZZ后别忘了把它归零:
my @grepped;
my $seen = 0;
while (my $line = <INFILE>) {
if ($line =~ /^ZZZ (.*)/) {
push @grepped, $1;
$seen = 0;
}
if ($line =~ /^ABC (.*)/) {
push @grepped, $1 if $seen++ == 1;
}
}
print "$_\n" for @grepped;
另一个选择是读取内循环中的下一行,但是你必须小心不要读过下一个ZZZ。
答案 1 :(得分:1)
我会将数字存储在哈希中并用它们做一些不错的魔法:)
#!/usr/bin/perl
use strict;
use warnings;
my $grepped;
my $active_n;
my $active_l;
while (my $line = <DATA>) {
chomp $line;
if ( $line =~ /^ZZZ/ ) {
$active_l = $line =~ s/^ZZZ //r;
} elsif ($line =~ /^ABC/) {
$active_n = $line =~ s/^ABC //r;
}
if ($active_l && $active_n) {
$grepped->{$active_l} = $active_n;
}
}
use Data::Dumper;
print map { "$_ => $grepped->{$_}\n"} sort keys $grepped;
__DATA__
ZZZ 111
ABC 523
ABC 835
ADD 234
ZZZ 222
ABC 0007
2935
ABC 4
ABC 893
wdq
ZZZ 333
ABC 777
ABC 00
编辑:
我的输出:
111 => 835
222 => 893
333 => 00