Tom Smith wrote:
>
> I'm writing a Perl script to parse 31 maillog files. The files are named
> maillog, maillog.1, and so on up to 31. This is the default logrotate
> scheme for naming rotated logs.
>
> My current order for processing these files is this:
>
> 1) Open the directory.
> 2) List maillog* files in the directory and assign them to @maillog.
> 3) Open each file in @maillog and search it for two specific strings.
> Assign matching strings to @parsedmail.
> 4) Print @parsedmail.
>
> I've tested the search string on a single maillog file and it works as
> expected, but putting this script together doesn't work correctly. I
> think it has something to do with the way I'm trying to pass the array
> to open(FILE...). The script is listed below.
>
> (Note that the maillogs in questions were moved from our mail server to
> a Windows machine for parsing. Also, the script is being run from the
> directory that contains the maillogs--hence the "." for the DIR to open.
> And "print @maillog" is hashed out as it tested good--that is, is prints
> the array and contains the file names I expected to be there.)
>
> #!C:\Perl\bin\perl.exe
>
> use strict;
> use warnings;
> use Carp;
>
> my @maillog;
> opendir(DIR, '.') or croak "Can't open .$!";
> while ($_ = readdir(DIR)) {
>    if($_ =~ /^maillog.*$/) {
>        push(@maillog,$_);
>    }
> }
> closedir DIR;
> #print @maillog;
>
> my @parsedmail;
> while ($_ = @maillog) {
>    open(FILE,'<$_') or croak "Can't open $_$!";
>    while($_ = <FILE>) {
>        if($_ =~ /.*imapd.*Log.*user.*$/ || /.*pop3d.*Log.*user.*$/) {
>            push(@parsedmail,$_);
>        }
>    }
>    close(FILE);
> }
> print @parsedmail;
>
>
> The error I get after executing this script is: "Can't open 32No such
> file or directory at H:\User Files\Mail Logs\parse.pl line 31" Maybe a
> coincidence, but "32" is the number of maillog files in this directory.
>
> Can anyone offer any advice for correcting this?

As you suspected, the reason for the failure is that

  $_ = @maillog

will assign the number of elements in the array to $_. Your code would probably
work as it is if you changed that line to

  while ($_ = shift @maillog) {
    :
  }

Below is a quick tidy-up of your program that you may like.

HTH,

Rob



use strict;
use warnings;

use Carp;

my @maillog = do {
  opendir my $dh, '.' or croak "Can't open directory: $!";
  grep /^maillog/, readdir $dh;
};

my @parsedmail;

foreach my $log (@maillog) {

  open my $fh, $log or croak "Can't open $log: $!";

  while (<$fh>) {

    if (/(?:imapd|pop3d).*Log.*user/) {
      push @parsedmail, $_;
      last;
    }
  }
}

print "$_\n" foreach @parsedmail;




--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to