Perl匹配一个值,然后匹配每个值的计数

时间:2019-06-11 18:40:56

标签: perl

所以我有一些以制表符分隔形式的数据:

Windows Department1 Enterprise
Windows Department1 Home
Linux   Department2 Santiago
Windows Department1 Professional
Windows Department1 Enterprise
Windows Department2 Enterprise

在这种情况下,我需要首先匹配第一列,并获取第二列和第三列中每个值的计数。排序以匹配完全匹配的数量。 所以最终得到这样的结果:

Windows Department1 Enterprise = 2
Windows Department2 Professional = 1
Linux   Department2 Santiago = 1
Windows Department3 Home = 1
Windows Department2 Enterprise = 1

所以我尝试了很多事情,这是最后一次尝试,但我得到了许多不同的不良结果:

use strict;
use warnings;
my %seen;
my $count = 0;
while (<INPUTFILE>) {
my ($app,$dep,$name) = split(/\t/,$_);
   if ($app.$dep.$name eq 'Windows.Department1.Professional') {
   unless ($seen{$app.$dep.name}++) {
     $count++;
      }
   }
}
print $app . " " . $dep . " " . $name . " " . $count++

但是这并不能满足我的需求。并仅打印带有计数的最后一个值。我想一次设置$app唯一,然后同时匹配第二个和第三个值以获得一个计数。除此之外,我需要手动将每个项目与eq匹配,并且上面的示例不会远程显示文件中的数据量,因此这会很麻烦。我将不胜感激。

1 个答案:

答案 0 :(得分:1)

首先构造一个由您要唯一计数的键组成的哈希:$ app,$ dep和$ name的组合。您可以为此使用组合键,但让我们使用多维哈希将键分开以备后用。当我们增加计数时,每个中间级别将自动为autovivified

use strict;
use warnings;
open my $input, '<', $filename or die "open $filename failed: $!";
my %counts;
while (my $line = <$input>) {
  chomp $line; # otherwise trailing field will contain a newline
  my ($app, $dep, $name) = split /\t/, $line;
  $counts{$app}{$dep}{$name}++;
}

然后遍历哈希以打印出每个计数。

foreach my $app (sort keys %counts) {
  my $app_counts = $counts{$app};
  foreach my $dep (sort keys %$app_counts) {
    my $dep_counts = $app_counts->{$dep};
    foreach my $name (sort keys %$dep_counts) {
      my $count = $dep_counts->{$name};
      print "$app $dep $name $count\n";
    }
  }
}