Re: Emptying Arrays



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
.



Relevant Pages

  • StorEdge 3310, disk sets, 2 hosts
    ... Hosts to be attached to the 3310 are a SunFire 280R and a ... array, while the other host is a cold standby. ... The 3310, even with just one controller, allows you to have just one ... Finally, has any done this before and is this setup (diskset, 2 ...
    (comp.unix.solaris)
  • Emptying Arrays
    ... 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. ... I thought that I could empty the array ... # chomp the array ...
    (perl.beginners)
  • Re: Masking internal hard disk on FC Loop
    ... shared array through a Fibre Channel hub. ... The problem is that other hosts can see the Blade internal drive. ... to an external hub to what shared array... ...
    (comp.sys.sun.admin)
  • Re: Different write speed on same SAN disks and same host
    ... but are all stored on the same SAN disks (they're different ... All of the LUNs come from the same Array, so I don't think it could be ... redundant controllers (so the hosts see 4 paths to each LUN). ...
    (comp.unix.solaris)
  • Re: deleting array stored in Hash
    ... > Does anyone know how I could delete the following array ... > which is pointed to by a hash key? ... Hash keys do not "point" to anything in Perl. ... > I dont just want to delete the pointer to ...
    (perl.beginners)