Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a script thats gathers cpu(using extract command) info for a numerous servers and prints the output to a file. It makes a file for a cluster thens removes it and then moves on to the next cluster. for example server1 and server2 would be cluster1 and server3 and server4 would be cluster2. I then open the output file and get a average for every hour for the day. The problem I have is when I print the average it prints it twice for each cluster because their is two servers in the cluster when i only need it to print once. Here is my code and example of my output file would look like.

sub get_avr { my ($cluster) = @_; open(IN, "$outputfile"); while (<IN>) { foreach my $hour (0 .. 23){ $_ =~ tr/ //s; ($date,$time,$cpu{$hour},$io,$rate,$mem) = split(/ /, $_); if ($time =~ /$hour:00/){ $tmem{$hour} = ($tmem{$hour} + $cpu{$hour}); $cnt{$time}++; $avr{$hour} = ($tmem{$hour} / $cnt{$time}); print "$cluster $time $avr{$hour}\n"; } } } }
my print would look something like this:
cluster1 00:00 43.45
cluster1 00:00 43.45 (But every hour would be printed)
this is the right infomation but i need it to print once not twice.
Here is what my outputfile would look like for a cluster before i open it:
05/08/06 00:00 51.84 1915510 1061 66.13
05/08/06 01:00 25.67 1255510 648 66.07
05/08/06 00:00 35.56 2077540 739 66.26
05/08/06 01:00 33.91 2262510 718 66.37
and of course their would be more the just the hours of 00:00 and 01:00. thanks for any help sorry for any thing that is miss typed.

Replies are listed 'Best First'.
Re: printing outside a for loop
by GrandFather (Saint) on May 09, 2006 at 01:53 UTC

    Something like this should get you headed in the right direction:

    use strict; use warnings; get_avr ('cluster1'); sub get_avr { my $cluster = shift; my %stats; while (<DATA>) { my ($date, $hour, $minutes, $load) = /(\S+)\s+(\d+)(\S+)\s+(\S ++)/; $stats{$hour}->[0] += $load; $stats{$hour}->[1]++; } for (sort keys %stats) { print "$cluster $_:00 " . $stats{$_}[0] / $stats{$_}[1] . "\n" +; } } __DATA__ 05/08/06 00:00 51.84 1915510 1061 66.13 05/08/06 01:00 25.67 1255510 648 66.07 05/08/06 00:00 35.56 2077540 739 66.26 05/08/06 01:00 33.91 2262510 718 66.37

    Prints:

    cluster1 00:00 43.7 cluster1 01:00 29.79

    DWIM is Perl's answer to Gödel
Re: printing outside a for loop
by jwkrahn (Abbot) on May 09, 2006 at 02:31 UTC
    You need to calculate the average outside the foreach loop.

    use warnings; use strict; # sub get_avr { # 'get' implies that the sub is returning a value? sub print_avr { my ( $cluster ) = @_ # open(IN, "$outputfile"); # Where does $outputfile come from? You should pass this value # to the subroutine instead of using globals. What happens when # you try to read from an invalid filehandle? open IN, '<', $outputfile or die "Cannot open '$outputfile' $!"; my %data; while ( <IN> ) { my ( $hour, $cpu ) = /(\d+):\d+\s+([\d.]+)/ or next; $data{ hour }{ total } += $cpu; $data{ hour }{ count }++; } close IN; for my $hour ( sort { $a <=> $b } keys %data ) { print "$cluster $hour:00 ", $data{ $hour }{ total } / $data{ $ +hour }{ count }, "\n"; }
Re: printing outside a for loop
by mildside (Friar) on May 09, 2006 at 01:50 UTC
    Anonymonk says:
    ... sorry for any thing that is miss typed.

    No need to apologise - women are welcome here.

    Cheers

    mildside

      Perhaps I should point out that this was a pun - a kind of joke.

      Oh ...(throws hands in air), never mind! My wife doesn't get my jokes either!

Re: printing outside a for loop
by mildside (Friar) on May 09, 2006 at 01:53 UTC
    Have you considered having two loops - one that gathers the statistics, and another that prints them out?

    Cheers

    mildside