4

私はこの形式のタブ区切りファイルを持っています:

Business System Name:  OK_CR                      

Serial Numbr  Service Name          Program Name          Epoch Start Time     
------------  --------------------  --------------------  -------------------  
GI1001TAA266  PPV 10 (50106)        We Bought A Zoo       Aug 14 2012  4:15AM  
GI1002TB3596  PPV 5 (50101)         Help, The (2011)      Aug 14 2012  6:30PM  
GI1002TDH825  PPV 2 (50098)         Safe House            Sep  7 2012  2:15AM  

Business System Name:  OK_SV                      

Serial Numbr  Service Name          Program Name          Epoch Start Time     
------------  --------------------  --------------------  -------------------  
GI1001TAA266  PPV 10 (50106)        We Bought A Zoo       Aug 14 2012  4:15AM  
GI1002TB3596  PPV 5 (50101)         Help, The (2011)      Aug 14 2012  6:30PM  
GI1002TDH825  PPV 2 (50098)         Safe House            Sep  7 2012  2:15AM  

ビジネス システム ヘッダーで区切られた日付ごとの行数をカウントしたいのですが、スクリプトの結果は次のようになります。

Business System Name:  OK_CR
Aug 14: 2
Sep 7: 1

Business System Name:  OK_SV
Aug 14: 2
Sep 7: 1

これまでのところ、ハッシュを作成しましたが、各日付をカウントし、各ビジネス システム ヘッダーの後にカウンターをリセットする方法に驚かされました。これは私のスクリプトです:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

open my $fh, '<', 'ppv.txt' or die $!;

my %data;
my $sect;
while (<$fh>) {
  next if /^\s+/;
  if (/^Business System Name:\s+(\w+)/) {
    $sect = $1;
    next;
  }
  #print "$sect\n";
  if (defined $sect) {
    next if /^Serial Numbr/;
    next if /^------------/;
    push @{ $data{$sect} }, $_;
  }
}
print Dumper \%data;

これはスクリプトの結果です:

$VAR1 = {
          'OK_CR' => [
                       'GI1001TAA266  PPV 10 (50106)        We Bought A Zoo       Aug 14 2012  4:15AM
',
                       'GI1002TB3596  PPV 5 (50101)         Help, The (2011)      Aug 14 2012  6:30PM
',
                       'GI1002TDH825  PPV 2 (50098)         Safe House            Sep  7 2012  2:15AM
'
                     ],
          'OK_SV' => [
                       'GI1001TAA266  PPV 10 (50106)        We Bought A Zoo       Aug 14 2012  4:15AM
',
                       'GI1002TB3596  PPV 5 (50101)         Help, The (2011)      Aug 14 2012  6:30PM
',
                       'GI1002TDH825  PPV 2 (50098)         Safe House            Sep  7 2012  2:15AM
'
                     ]
        };

ここから先に進む方法について何か考えはありますか?

4

3 に答える 3

1

Perl のレコード セパレータ ( $/) を「ビジネス システム名:」に設定する別のオプションを次に示します。これにより、ファイルはこれらのチャンクでレコードとして読み込まれます。splitファイルにはタブ区切りのデータが含まれているため、日付行も\t表示されます。

use strict;
use warnings;
use Data::Dumper;

local $/ = 'Business System Name:';
my %data;

while (<>) {
    my ($sect) = /\s+(.+)/;
    my @timeLines = grep /:\d\d(?:A|P)M$/, split /\n/;
    for (@timeLines) {
        ( split /\t/ )[-1] =~ /(.+?)\s+\d+:/;
        $data{$sect}{$1}++;
    }
}

print Dumper \%data

使用法:perl script.pl inFile [>outFile]

最後のオプション パラメータは、出力をファイルに送信します。

データセットの出力:

$VAR1 = {
          'OK_SV                      ' => {
                                             'Aug 14 2012' => 2,
                                             'Sep  7 2012' => 1
                                           },
          'OK_CR                      ' => {
                                             'Aug 14 2012' => 2,
                                             'Sep  7 2012' => 1
                                           }
        };

レコードが読み取られた後、セクション名が取得されます。次に、レコードの行はsplit改行でありgrep、時刻データを含む行のみに対して ped が実行されます。タブ文字の最後のforループsplits は、最後のフィールドを取得し、日付情報を取得してから、宗派と日付のデータでハッシュをインクリメントします。

お役に立てれば!

于 2013-11-06T21:18:09.373 に答える
1

を使用するunpackと、コメントのように、各日付の番号を追跡するだけで済みます。

use strict;
use warnings;
use Data::Dumper;

open my $fh, '<', 'ppv.txt' or die $!;

my %data;
my $sect;
while (<$fh>) {
  next if /^\s+/;
  if (/^Business System Name:\s+(\w+)/) {
    $sect = $1;
    next;
  }
  #print "$sect\n";
  if (defined $sect) {
    next if /^Serial Numbr/;
    next if /^------------/;
    my $format = 'A57 A13 A*';
    my($prefixes, $date, $suffixes) = unpack($format, $_);
    $data{$sect}{$date}++;
  }
}
print Dumper \%data;

__END__

$VAR1 = {
          'OK_CR' => {
                       ' Aug 14 2012' => 2,
                       ' Sep  7 2012' => 1
                     },
          'OK_SV' => {
                       ' Aug 14 2012' => 2,
                       ' Sep  7 2012' => 1
                     }
        };
于 2013-11-06T16:53:20.490 に答える
1

これはうまくいくはずです:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my %hash =();
open(FILE,"test.txt");
while(<FILE>)
{
    if(/(Business System Name:\s+OK_\S+)\s+/)
    {
        if(%hash)
        {
            print Dumper \%hash;
            %hash=();
            $hash{header}=$1;
        }
        else
        {
            $hash{header}=$1;
        }
    }
    elsif(/((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+\s+\d\d\d\d)/)
    {
        if(defined $hash{$1}){$hash{$1}++;}
        else{$hash{$1}=1;}
    }
}
close(FILE);
if(%hash)
{
    print Dumper \%hash;
}

出力:

$VAR1 = {
          'Aug 14 2012' => 2,
          'Sep  7 2012' => 1,
          'header' => 'Business System Name:  OK_CR'
        };
$VAR1 = {
          'Aug 14 2012' => 2,
          'Sep  7 2012' => 1,
          'header' => 'Business System Name:  OK_SV'
        };
于 2013-11-06T16:59:26.327 に答える