Perl 如何计算数组列数据?

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

以下是完整代码:

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";
}
我在系统帐户数据文件中循环,收集每个系统用户的数据行,并将其推送到一个名为@all的数组中

然后我在@all上对每个用户进行grepping并将其发送到@data数组。如果I
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$2total、$3total、$4total等

由于您是在
@array
中获取值的,因此以这种方式处理数组

获得
@array
后,您可以在代码中添加以下代码

#!/usr/bin/perl

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

my @data = (
'cp1556                                1       0.01re       0.01cp         0avio     22336',
'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'
);

my %hash;

foreach my $line (@data){
    my @each_line = split /\s+/, $line;
    $hash{$each_line[0]}{'Col1'} += $each_line[1];
    
    ($each_line[2] = $each_line[2]) =~ s/re$//;
    $hash{$each_line[0]}{'Col2'} += $each_line[2];
    
    ($each_line[3] = $each_line[3]) =~ s/cp$//;
    $hash{$each_line[0]}{'Col3'} += $each_line[3];
    
    ($each_line[4] = $each_line[4]) =~ s/avio$//;
    $hash{$each_line[0]}{'Col4'} += $each_line[4];
    
    ($each_line[5] = $each_line[5]) =~ s/k$//;
    $hash{$each_line[0]}{'Col5'} += $each_line[5];
}

foreach my $cp(keys %hash){
    print "$cp, $hash{$cp}{'Col1'}, $hash{$cp}{'Col2'}re, $hash{$cp}{'Col3'}cp, $hash{$cp}{'Col4'}avio, $hash{$cp}{'Col5'}k\n";
}

让我知道您在这里得到了预期的答案。

您可以将过滤和汇总每个用户的输入移动到单个循环中。不需要重复两次

使用严格;
使用警告;
使用数据::转储程序;
my@cplist=qw(cp1556cp1449)#使用者
我的@sau数据=;#qx()
我的%wanted_users=map{$_=>1}@cplist;#建立一个查找表
我的%金额;
foreach my$行(@sau data){
#破门而入
my@cols=split/\s+/,$line;
#是否要为此用户收集数据?
如果(存在$U用户{$cols[0]}){
我的$i(1,2,3,5){
(我的$number=$cols[$i])=~s/[^\d.]//g;
$sums{$cols[0]}{$i}+=$number;
}
}
}
打印转储文件\%和;
__资料__
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
此代码从
数据
文件句柄读取,而不是从
qx()
读取

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

然后,我们将数据行拆分为列,尽可能使用空格分隔符。这可能是因为它实际上是标签,但这并不重要

我们通过查看是否有散列条目来检查第一列中的用户是否是我们关心的用户。然后,我们取我们关心的列数,并将它们相加。我假设我们不关心最后一列,因为它看起来不是一个数值

我们需要清理这些单位(或其他任何单位)。在将正则表达式赋给变量
$number
后,我们用正则表达式替换所有非数字和非文字点(
)的字符。然后我们用它来建立总和

我们将其存储在
%sums
散列中,每个用户需要一个密钥。每个用户都有一个哈希引用,列号作为键。散列在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};

你试过什么吗?显示您的代码是件好事如果数据存储在
@data
中,那么
$data[0]
将是您的第一个cplist,
$data[1]
将是您的第二个cplist,依此类推。。取出
$data[0]
并用
空格
拆分
,从所需列中获取值并求和。您没有向我们显示整个代码,比如
@all
数组中的值是什么?问题并添加您的代码。@SamNetworks.IN:
cp1449
的预期输出是否应如下所示<代码>cp1449 11 0.33re 0.15cp 0avio 77572k
这似乎是所有列的总和,但没有进行筛选。感谢您撰写此文章。1.是否
=~s/[^\d.]//gr应该是
=~s/[^\d.]//g2。你认为我不需要“全部”?仅仅@sau数据就足够了吗?代码正在运行,但数据不符合预期。只有1位数组。@SamNetworks.IN no,它是故意的
s///gr
。正如我在解释中所说的,
/r
使其返回被替换的值,而不是更改调用它的变量。如果去掉
/r
,它将返回替换数。`Bareword在cpu.pl第49行的“s/[^\d.]//gr”附近找到运算符,在cpu.pl第49行的“s/[^\d.]//gr”附近出现语法错误,cpu.pl的执行因编译错误而中止。`因此将其更改为:`~s/[^0-9.]+//g;`对不起,我是Perl新手,正在尽我最大的努力。@SamNetworks.IN啊,你的Perl真的很旧了。
/r
于2011年发布。那是10年前的事了。我们需要增加第二步。我来编辑。