【发布时间】:2017-07-13 19:50:10
【问题描述】:
我正在使用 Perl 5.8.8 分析日志文件。[1] 我正在寻找暴露两种触发模式中的一些的日子,可能是其中之一,也可能是两者(我更改了代码 sn-p 中的实际模式如下所示)。我对每天的出现次数感兴趣,下一步将是制作一个电子表格,这就是使用制表符进行输出格式化的原因。
因为一天中可能只出现一种模式,所以我需要一种方法来组合两个哈希的键。我通过生成一个新的哈希来做到这一点。有内置功能吗?我搜索了网络和堆栈溢出没有任何结果,我在这里得到的唯一命中是Build a string from 2 hashes,但在那种情况下,密钥集是相同的。
#!/usr/bin/perl -w
use strict;
use warnings;
use locale;
# input analysis: searching for two patterns:
my %pattern_a = ();
my %pattern_b = ();
foreach my $line (<>) {
if ($line =~ m/^(\d{4}-\d{2}-\d{2})(.+)$/) {
my $day = $1;
my $what = $2;
if ($what =~ m/beendet/) {
$pattern_a{$day} ++;
} elsif ($what =~ m/ohne/) {
$pattern_b{$day} ++;
}
}
}
# generate the union of hash keys: <-- In Question
my %union = ();
$union{$_} = 1 for keys %pattern_a;
$union{$_} = 1 for keys %pattern_b;
# formatted output sorted by day:
foreach my $day (sort keys %union) {
print join "\t", $day,
($pattern_a{$day} || 0),
($pattern_b{$day} || 0)."\n";
}
预期的输出如下所示:
2017-02-01 0 1
2017-02-18 0 592
2017-02-19 2 0
[1] 我知道这个 Perl 版本已经过时了。但是我很少使用 Perl,但是当我使用时,它必须运行得很快。因此,弄清楚 Perl 版本等等会在以后完成。但是 Perl 版本对于实际问题并不那么重要,至少我希望如此......
【问题讨论】:
-
不要命名
$a和$b。这些变量保留用于sort块。结合到底是什么意思?你能展示你想要的最终输出吗?我认为您选择了一种复杂的方法。这可以简化,但我们需要看看你想要什么。最有效的数据结构取决于最终产品。 -
是的,^ 说的。
-
@simbabque 当然,$a 和 $b 不好,已修复,感谢您指出这一点。
-
我听起来像个挑剔的人,但全大写的变量名并不好。它们看起来像常数。此外,单字母变量不会说话,因此很难猜测它们的用途。为什么不将该部分重写为
say join "\t", $day, $pattern_a{$day} // 0, $pattern_b{$day} // 0;,然后您就不再需要该变量了。您也不需要使用那些括号(),因为您使用了低杆or而不是||,在这种情况下这是错误的,因为如果已经有@987654331,它也会是错误的无论如何@在那个变量中。//是定义或,这样更好。 -
@Gerry,添加了 simbabque 示例输出。
标签: perl hash log-analysis set-union perl5.8