完整代码如下:
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/