【问题标题】:Counting total sum of each value in one column w.r.t another in Perl在Perl中计算一列中每个值的总和
【发布时间】:2011-06-29 11:34:03
【问题描述】:

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

我在第 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";
}

所以,结果会是这样的

Windows    100000
Linux        5000
Mac OSX     15000
Android      2000

但此代码中似乎存在一些错误,因为我得到的结果值与预期不符。

我做错了什么?

【问题讨论】:

  • 如果您实际提供了导致问题的示例输入、实际输出和预期输出,我会考虑对您的问题进行投票(关于样式,而不是错误本身)

标签: perl parsing


【解决方案1】:

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

$count{$line[30]} = $line[5] + $line[6];

应该是

$count{$line[30]} += $line[5] + $line[6];

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

  1. 请使用 3 参数形式的打开和词法文件句柄:

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

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

  4. 请不要使用 1 个字母的变量。 $w 在最后一个循环中是没有意义的,而$os_name 是明确的。

【讨论】:

  • 这很尴尬。这样一个基本的错误:)。谢谢你的建议。
  • @sfactor - 如果这是你犯过的最令人尴尬的错误,请认为自己很幸运 :) 我的情况更糟
【解决方案2】:

你的表情

open F, $f || die "Cannot open $f: $!";

其中有一个微妙的错误,最终会咬你,尽管今天可​​能不会。

|| 运算符的优先级高于其左侧的逗号运算符,因此该表达式实际上被解析为

open F, ($f || die "Cannot open $f: $!")

也就是说,当$f 的值为假(0、""undef)时,您将die,而不是当open 语句无法打开具有给定名称的文件时$f.

按照你的意思,你可以使用括号:

open (F, $f) || die ...

或使用备用低优先级 or 运算符

open F, $f  or  die ...

(At times I have been bitten by this myself)

【讨论】:

    【解决方案3】:
    $count{$line[30]} = $line[5] + $line[6];
    

    应使用 += 运算符将行的总和添加到总计,而不是将其设置为总计:

    $count{$line[30]} += $line[5] + $line[6];
    

    【讨论】:

    • TFGITW?第一个有趣的词缠结?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2021-12-18
    • 2022-12-15
    • 1970-01-01
    相关资源
    最近更新 更多