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/