On Jun 28, Ryan Frantz said:
I'm working on a script that iterates over a log file looking for known
hosts so that their messages can be grouped in a summary report.
However, when I run the script, the array I create includes entries for
previous hosts that were found. I thought that I could empty the array
at the beginning of the loop but this did not work. Any ideas would be
appreciated; see code below:
The @lines array is only half your issue -- you also need to clear the
%line_count hash.
But this could be made a whole lot simpler by PROPERLY scoping your
variables. Don't declare all of them at the top of your program, declare
them in the scope in which they should exist.
#!/usr/bin/perl
use strict;
use warnings;
my @logfile = <>;
my @hosts = qw( ... );
my @keywords = qw( ... );
Ok, that's good so far. Now, when you do:
for my $x (@y) {
$x =~ s/this/that/;
}
you're *actually* modifying the elements in @y, because $x isn't a *copy*
of each element, it's an *alias* to each element. Therefore, instead of
looping over @logfile and doing substitutions each time, let's fix up the
contents of the array right now before we go on:
for (@logfile) {
s/\d+/#/g;
s/^.*: //;
chomp;
}
Ok, now we can continue:
for my $host (@hosts) {
my @lines;
for (@logfile) {
push @lines, $_ if /$host/i;
}
Let's rewrite that. That could be done as a grep() statement:
my @lines = grep /$host/i, @logfile;
Now we work with %line_count.
my %line_count;
for (@lines) {
$line_count{$_}++;
}
You don't need to do the special-case stuff you had. If a hash key
doesn't exist yet, and you use it like it DOES exist, Perl adds it for
you, no questions asked.
Then you go through this hash and print it:
for (sort keys %line_count) {
print "$_: $line_count{$_}\n";
}
}
But we can go one step further: @lines is only used twice -- we put stuff
into it, and then we read from it. We can get rid of the array and just
use the return value from grep() in-place:
for my $host (@hosts) {
my %freq;
$freq{$_}++ for grep /$host/i, @logfile;
# open file
for (sort keys %freq) {
print "$_: $freq{$_}\n";
}
# close file
}
Voila.
--
Jeff "japhy" Pinyan % How can we ever be the sold short or
RPI Acacia Brother #734 % the cheated, we who for every service
http://japhy.perlmonk.org/ % have long ago been overpaid?
http://www.perlmonks.org/ % -- Meister Eckhart
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>