perl - Perl如何计算数组列数据?

标签 perl

完整代码如下:

foreach my $file (@safiles) {
    @sa_data = qx(/usr/sbin/sa -m $file);
       foreach my $user (@cplist) {
       push(@all, grep { /$user/ } @sa_data);
  }
}

foreach  my $user (@cplist) {
    @data = grep { /$user/ } @all;
    print @data;
    print ".............\n";
}

我正在循环系统 acct 数据文件并收集每个系统用户的行并将其推送到名为 @all 的数组。

然后我在 @all 上 grep 每个用户并将其发送到 @data 数组。如果我 print @data 它会批量显示每个用户的数据:

cp1556                                1       0.01re       0.01cp         0avio     22336k
cp1556                                1       0.01re       0.01cp         0avio     22336k
cp1556                               63     862.28re       0.17cp         0avio     13839k
cp1556                               43     176.03re       0.13cp         0avio     12083k
cp1556                               40     653.49re       0.12cp         0avio     13258k
cp1556                               30     506.61re       0.05cp         0avio     12177k
cp1556                                4       0.02re       0.02cp         0avio     19736k
.............
cp1449                                  6       0.26re       0.11cp         0avio     30176k
cp1449                                  3       0.07re       0.04cp         0avio     30261k
cp1449                                  2       0.00re       0.00cp         0avio     17135k

现在我想对此处输出 == 的列进行求和 cp1449 总计 2 美元、总计 3 美元、总计 4 美元等

最佳答案

您可以将过滤和汇总每个用户的输入移至单个循环中。无需迭代两次。

use strict;
use warnings;
use Data::Dumper;

my @cplist = qw(cp1556 cp1449); # users
my @sa_data = <DATA>; # qx()

my %wanted_users = map { $_ => 1 } @cplist; # build a lookup table
my %sums;
foreach my $line (@sa_data) {
    # break into colums
    my @cols = split /\s+/, $line;

    # do we want to collect data for this user?
    if (exists $wanted_users{$cols[0]}) {
        for my $i ( 1, 2, 3, 5 ) {
            ( my $number = $cols[$i] ) =~ s/[^\d.]//g;
            $sums{$cols[0]}{$i} += $number;
        }
    }
}

print Dumper \%sums;

__DATA__
cp1556                                1       0.01re       0.01cp         0avio     22336k
cp1556                                1       0.01re       0.01cp         0avio     22336k
cp1556                               63     862.28re       0.17cp         0avio     13839k
cp1556                               43     176.03re       0.13cp         0avio     12083k
cp1556                               40     653.49re       0.12cp         0avio     13258k
cp1556                               30     506.61re       0.05cp         0avio     12177k
cp1556                                4       0.02re       0.02cp         0avio     19736k
.............
cp1449                                  6       0.26re       0.11cp         0avio     30176k
cp1449                                  3       0.07re       0.04cp         0avio     30261k
cp1449                                  2       0.00re       0.00cp         0avio     17135k

此代码从 DATA 文件句柄读取,而不是从 qx() 读取。

我为我们感兴趣的用户创建了一个查找哈希,该哈希来自 @cplist。检查哈希键是否存在比进行模式匹配并存储包含所有行的额外数组要便宜得多。

然后,我们将数据行分成尽可能多的空白分隔符的列。可能它实际上是选项卡,但这并不重要。

我们通过查看是否存在其哈希条目来检查第一列中的用户是否是我们关心的用户。然后我们获取我们关心的列号并对它们进行总结。我假设我们不关心最后一列,因为它看起来不是一个数值。

我们需要清理这些单位(或者无论它们是什么)。为此,我们将所有非数字和非文字点 (.) 的字符分配给变量 $number 后用正则表达式替换。然后我们用它来求和。

我们将其存储在 %sums 哈希中,并为每个用户提供一个我们想要的 key 。每个用户都有一个以列号作为键的哈希引用。 Perl 中的哈希值没有排序,所以看起来很乱,但这只是内部表示。它们以 0 开始,没有初始化。

当我们打印数据结构时,我们得到这个输出。

$VAR1 = {
          'cp1449' => {
                        '5' => 77572,
                        '1' => 11,
                        '3' => '0.15',
                        '2' => '0.33'
                      },
          'cp1556' => {
                        '2' => '2198.45',
                        '3' => '0.51',
                        '1' => 182,
                        '5' => 115765
                      }
        };

您可以像这样检索单个值:

print $sums{cp1556}{2};

关于perl - Perl如何计算数组列数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66349658/

相关文章:

perl - 获取代码点的所有 Unicode 别名

regex - 如何在 perl 中拆分和保留拆分标准

regex - perl - 从函数定义中提取参数并将其作为注释放在上面

perl - 为什么 Email::Stuffer base64 编码与 MIME::Base64 不同以及 utf8 如何适应?

oracle - 在perl脚本中调用带有输入参数和输出光标的存储过程

perl - Perl 中元音变音 "ü"的正确存储值是多少?

perl - 驼鹿触发调用者

c++ - "value-based"OR 运算符的通用术语

perl - 如何不匹配字符串?

perl - 在 perl 中,我如何从通过文本文件并在 dd-Month-YYYY(01-jan-1990) 中输出的日期中减去 10 天