Perl哈希到CSV

时间:2014-05-01 23:50:17

标签: arrays perl parsing csv hash

我有一个数据文件,用于白天发生的警报。格式类似于

2014/04/27-23:42:22.177742- Alarm1
2014/04/27-23:42:22.177744- Alarm2
2014/04/27-23:42:22.177747- Alarm3
2014/04/27-23:42:22.177749- Alarm1

现在我无法猜出何时出现任何警报。这取决于系统。我所做的是将警报数据(例如Alarm1)插入2D哈希。我每次花费大约5分钟,并寻找在5分钟内出现的警报。每当我发现新警报时,我都会将值添加到哈希值中。如果重复(如上面的Alarm1),我只需在值中加1。所以最后它会给我一个哈希,其中包含警报名称和它在5分钟内出现的次数。 接下来我将在接下来的5分钟内开始处理。

我正在处理它一整天,所以有可能1个闹钟可以在早上10点开始出现,所以这将是哈希的一个新条目。现在我尝试将值最终打印到CSV,这是一团糟。完全没有意义。我期望的是一个看起来像

的csv
Name,00:00,00:05,00:10,
Alarm1,2,5,2,7,
Alarm2,4,7,3,6
Alarm3,6,1,6,3
...

我的代码是:

use Time::Local;
use POSIX 'strftime';
use Data::Dumper;


my %outputHash= ();

$curr = timelocal(0, 0, 0, (split /\//, $ARGV[0])[1], (split /\//, $ARGV[0])[0]-1, (split /\//, $ARGV[0])[-1]);
$currentTime = strftime "%Y/%m/%d-%H:%M:%S", localtime($curr);
for ($count = 1; $count <= 288; $count++) { #there are 288 '5 minutes' in a day.
    $curr += 300;
    $nextTime = strftime "%Y/%m/%d-%H:%M:%S", localtime($curr);
        $cmd = "awk '\$0>=from&&\$0<=to' from=\"$currentTime\" to=\"$nextTime\" Output.txt";
            my $dataChunk = qx($cmd);
            my @lines = split /[\n]+/, $dataChunk;
        foreach my $line (@lines) {
            chomp;
            $timeStamp1 = substr($line,21,6);
            #print "\n$timeStamp1\n$error\n";
            if ($timeStamp1 != $timeStamp2){
                $outputHash{$error}{$count} = $outputHash{$error}{$count} + 1;
            }
            $ind = index($line,'- ') + 2;
            $len = length($line) - $ind;
            $error = substr($line,$ind, $len);
            $timeStamp2 = $timeStamp1;
        }
    $currentTime = $nextTime;
#   if ($count>3){$count=300;}
}
`>/tmp/report.txt`;
open (MYFILE, '>>/tmp/report.txt'); 
my @outputArray = ();
my $flag =1;
foreach my $error (sort keys %outputHash)
{
    print MYFILE "$error,";
    #$outputArray[$flag][0] = $error;
    for ($count=1,$count <= 288, $count++)
    {
        print MYFILE "$outputHash{$error}{$count},";
        #$outputArray[$flag][$count] = int($outputHash{$error}{$count});
    }
    $flag += 1;print MYFILE "\n";
}
close (MYFILE);
#print Dumper(\@outputArray);
exit;

我的简化显示看起来像这样。其偶然的原因是因为报警1仅在“第二”5分钟间隔内发生,报警2仅在第1次发生,报警3在连续4分钟内发生,我们监测到。

'Alarm1{
    '2' => '5'
  },
'Alarm2{
    '1' => '1'
  },
'Alarm3
'4' => '1',
'1' => '2',
'3' => '1',
'2' => '1'
   },

1 个答案:

答案 0 :(得分:0)

尝试这一点,如果你使用一个用于处理CSV的模块,那就最好了。

我选择了Class::CSV,因为它很简单。

#!/usr/bin/perl

use strict;
use warnings;
use Class::CSV;

my %hash = (
    'Alarm1' => {'2' => '5', },
    'Alarm2' => {'1' => '1', },
    'Alarm3' => {
        '4' => '1',
        '1' => '2',
        '3' => '1',
        '2' => '1'
      },
);
my @fields = qw/AlarmNo 00:00:00 00:05:00 00:10:00 00:15:00/;
my $csv = Class::CSV->new( fields => \@fields );

#make the hash into a suitable array

my @array;
my @keys = keys %hash;

for my $i (0 .. $#keys){
        push @{ $array[$i] }, $keys[$i];
        for my $inter (1 .. 4){
            my $val = '';
            if(exists $hash{$keys[$i]}->{$inter}){
                $val = $hash{$keys[$i]}->{$inter};
            }
            push @{ $array[$i] }, $val;
        }
}

$csv->add_line($_) for(@array);
print join(',', @fields), "\n"; #Just to make it tidy on the commandline
$csv->print();

因此,您可以使用print MYFILE $csv->string将其存入您的文件。

编辑:

如果您无法安装Class :: CSV,请查看可能默认安装的Text :: CSV。

你也可以用逗号这样加入数组

for(@array){
    print join(',', @{$_});
}