1

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 の行で 1 つおきのエントリのみを取得するために、次のことを試しました。

#!/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
4

2 に答える 2

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;

もう 1 つのオプションは、内側のループで次の行を読み取ることですが、次の ZZZ を超えて読み取らないように注意する必要があります。

于 2013-08-09T13:01:36.983 に答える
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
于 2013-08-09T13:06:34.737 に答える