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/