【问题标题】:Perl Hash to CSVPerl 哈希到 CSV
【发布时间】:2014-06-18 13:48:18
【问题描述】:

我有一个白天发生警报的数据文件。格式看起来像

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 分钟。

我一整天都在处理它,所以有可能在早上 10 点开始出现 1 个警报,所以这将是哈希的一个新条目。现在,当我尝试最终将值打印到 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 仅在“第 2 个”5 分钟间隔内发生,警报 2 仅在第 1 个发生,警报 3 在我们监测的 4 个连续 5 分钟间隔内发生。

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

【问题讨论】:

  • 你能发布你的哈希结构吗?
  • 刚刚编辑它以包含哈希

标签: arrays perl parsing csv hash


【解决方案1】:

试试这个,最好是使用一个用于处理 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-&gt;string 将其放入您的文件中。

编辑:

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

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

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

【讨论】:

  • 由于某些原因,我无法安装 Class::CSV。我如何在不安装的情况下使用这个库?放到脚本目录下?
  • @user3195304 查看 Perl 安装随附的 Text::CSV。我将编辑我的答案以添加使用加入来制作 csv
  • 在另一个方面,我正在使用 #!/usr/bin/perl use lib '/tmp/report/modules';并且 Class::CSV 在那里,但它无法以某种方式找到它。很奇怪。
  • 还有一件事,我的哈希插入效果不佳。我需要的是动态地将条目添加到哈希中。假设我在读取文本文件时遇到“Alarm1”字符串。我将不得不插入哈希。我现在正在做的是 " $outputHash{"$error"}{"$count"} = $outputHash{"$error"}{"$count"} + 1; " ... 其中 $error 是 " Alarm1" & $count 是间隔。每当我遇到一个新实例时,我都会为该值添加 +1。
猜你喜欢
  • 2016-04-03
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
  • 2013-12-20
  • 2013-08-10
  • 1970-01-01
  • 2013-09-21
相关资源
最近更新 更多