Perl:计数脚本做错了吗?

use*_*323 1 perl zimbra

我的剧本:

#!/usr//bin/perl
#
# Script to balance accounts between servers
# By Philip Gabrielsen
#    
use strict;
use warnings;    
START:
print "\nZimbra account moving script\n";
print "First we will collect data from Zimbra, this may take a while.\n\n";

my %accounts;
DATACOLLECT:
print "Collecting Zimbra mailbox server(s)... ";
my $servers = `zmprov gas mailbox`;
print "OK\n";

print "Collecting numbers of accounts per server... ";
foreach my $server (split(/\n/, $servers)) {
  $accounts{$server} = `zmprov -l gaa -s $server|wc -l`;
}
print "OK\n";

foreach my $server (keys %accounts) {
  print "\nServer $server with ". $accounts{$server} ." accounts\n";
}

print "TEST, is total number of accounts good?";
$accounts{'total'} = 0;
foreach my $server1 (keys %accounts) {
  $accounts{'total'} = $accounts{'total'} + $accounts{$server1};
  print "\nAdded $accounts{$server1} and total is now $accounts{'total'}";
}
print "\nTotal number of accounts: $accounts{'total'}\n";
Run Code Online (Sandbox Code Playgroud)

输出:[zimbra @ snake tmp] $ perl accounts.pl

Zimbra account moving script
First we will collect data from Zimbra, this may take a while.

Collecting Zimbra mailbox server(s)... OK
Collecting numbers of accounts per server... OK

Server snake with 363
 accounts

Server tiger with 431
 accounts

Server lion with 273
 accounts
TEST, is total number of accounts good?
Added 363
 and total is now 363
Added 431
 and total is now 794
Added [zimbra@tiberius tmp]$ perl accounts.pl

Zimbra account moving script
First we will collect data from Zimbra, this may take a while.

Collecting Zimbra mailbox server(s)... OK
Collecting numbers of accounts per server... OK

Server titus.zimbra.h.bitbit.net with 363
 accounts

Server tiberius.zimbra.h.bitbit.net with 431
 accounts

Server otho.zimbra.h.bitbit.net with 273
 accounts
TEST, is total number of accounts good?
Added 363
 and total is now 363
Added 431
 and total is now 794
Added 1588 and total is now 1588
Added 273
 and total is now 1861
Total number of accounts: 1861 and total is now 1588
Added 273
 and total is now 1861
Total number of accounts: 1861
Run Code Online (Sandbox Code Playgroud)

首先看到,当从每个服务器列出帐户时,显示正确的数字,但最后一部分,当我想将所有$帐户添加到总值时,弹出数字1588,这应该是273 ...

TLP*_*TLP 5

我不得不承认,有一段时间你让我难过.但后来我意识到这段代码不正确:

$accounts{'total'} = 0;                 # here you add a key to the serverlist
foreach my $server1 (keys %accounts) {  # here you list all keys
  $accounts{'total'} = $accounts{'total'} + $accounts{$server1};
  print "\nAdded $accounts{$server1} and total is now $accounts{'total'}";
}
Run Code Online (Sandbox Code Playgroud)

因为密钥total是同一哈希中的密钥之一:

titus.zimbra.h.bitbit.net
tiberius.zimbra.h.bitbit.net
otho.zimbra.h.bitbit.net 
total
Run Code Online (Sandbox Code Playgroud)

因此,当您到达键列表中的点时total,您会看到总计双倍,从794到1588.

答案是不使用相同的哈希来存储您的总和.事实上,为什么要使用哈希呢?

my $total = 0;                    # independent scalar 
foreach my $server1 (keys %accounts) {
  $total += $accounts{$server1};
  print "\nAdded $accounts{$server1} and total is now $total";
}
Run Code Online (Sandbox Code Playgroud)

另外值得注意的是,你在评论中说chomp你把所有的数字都变为1.你可能使用了chomp错误,这是一个常见的初学者错误.

$count = chomp($count);      # WRONG! chomp returns number of newlines removed
chomp($count);               # Correct. chomp modifies its argument variable
Run Code Online (Sandbox Code Playgroud)

您可能会问chomp,返回删除的换行符的数量有多好,答案是它也可以用于数组和散列:

my $removed = chomp(@array); # See how many newlines were removed 
Run Code Online (Sandbox Code Playgroud)