在Perl中计算一列中每个值的总和

sfa*_*tor 1 perl parsing

我有多列的制表符分隔数据.

我在第31列中有操作系统名称,在第6列和第7列中有数据字节.我想要做的是计算每个唯一操作系统的总容量.

所以,我在Perl中做了这样的事情:

#!/usr/bin/perl
use warnings;

my @hhfilelist  = glob "*.txt";
my %count = ();

for my $f (@hhfilelist) {
    open F, $f || die "Cannot open $f: $!";
    while (<F>) {
        chomp;
        my @line = split /\t/;
        # counting volumes in col 6 and 7 for 31
        $count{$line[30]} = $line[5] + $line[6];     
    }
    close (F);
}

my $w = 0;

foreach $w (sort keys %count) {
    print "$w\t$count{$w}\n";
}
Run Code Online (Sandbox Code Playgroud)

所以,结果会是这样的

Windows    100000
Linux        5000
Mac OSX     15000
Android      2000
Run Code Online (Sandbox Code Playgroud)

但是在这段代码中似乎有一些错误,因为我得到的结果值并不像预期的那样.

我究竟做错了什么?

DVK*_*DVK 6

看起来你实际上并没有添加计数 - 你用该操作系统最后一行的计数覆盖任何操作系统的最后计数.

$count{$line[30]} = $line[5] + $line[6];
Run Code Online (Sandbox Code Playgroud)

应该

$count{$line[30]} += $line[5] + $line[6];
Run Code Online (Sandbox Code Playgroud)

作为可以改善整体代码但不影响其正确性的其他注意事项:

  1. 请使用3参数形式的open和Lexical文件句柄:

     open(my $filehandle, "<", $f) || die "Cannot open $f: $!";
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您100%确定您的文件在字段内容中不包含带引号的字段值或选项卡,则split基于您的逻辑是正常的.对于非常复杂的X分隔文件,我强烈建议使用Text::CSV_XS/ Text::CSVCPAN模块

  3. 不需要初始化%count$w变量 - 哈希将自动初始化为空哈希,$w并被分配为循环变量 - 您可能希望实际在循环中声明它:foreach my $w (sort keys %count) {

  4. 请不要使用单字母变量.$w在最后一个循环中没有意义,但$os_name很清楚.