in reply to Tricky Syslog Parsing

Having been faced with solving a very similar problem not that long ago let me pass along one lesson that I learned: Create regexs using qq() and test each one one at a time.

Caveat:All the following code has not been tested

Looking at the examples you ahve provided here are a few thoughts.

my $dtg=qq@\d+\-\d+\-\d+\s\d+:\d+:\d+@; # Date time group my $logtype=qw@Local\d\.[Error|Critical]@; # Log type my $ipaddr=qw@\d+\.\d+\.\d+\.\d+@; # IP Address my $odtg=qq@[A-Za-z]{3}\s\d+\s\d+\s\d+:\d+:\d+:@; my $select=qq@%FW\-\d+\-\d+@; # FW or PIX? my $match_line=qq@$dtg\s+$logtype\s+$ipaddr\s+$otg\s+$select@;
Now you can take each of the regexs that make up the big regex and test them one at a time and see if they work.

Two other comments:

  1. Are you trying to match %PIX or %FW?
  2. What does next unless $1 !~ /$1/; mean in the logic of your code?


Peter L. Berghold -- Unix Professional
Peter at Berghold dot Net
   Dog trainer, dog agility exhibitor, brewer of fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and a good Belgian ale in your chalice.

Replies are listed 'Best First'.
Re: Re: Tricky Syslog Parsing
by Dru (Hermit) on Jan 13, 2004 at 19:21 UTC
    Much appreciated Monks. You still haven't let me down yet.

    This might not be the best method/code, but here's how I got it working. Any improvements welcome (I don't know why I have to use open twice, if I never close FILE, but it doesn't work otherwise):
    my $file = 'd:\PROGRA~1\Syslogd\Logs\syslog22Dec2003.txt'; open (FILE, $file) or die "Can't open $file: $!\n"; my %messages; while(<FILE>) { /(FW\-\d+\-\d+)/; # extract MSG ID next if exists($messages{$1}); # ignore it if we've $messages{$1} = $1; # already seen it. } my $count; open (FILE, $file) or die "Can't open $file: $!\n"; for my $i (keys %messages){ print "\n$i:\n\n"; $count = 0; while(<FILE>){ if (/$i/){ print "$_\n"; $count++; } last if $count == 1; } } close FILE;
      Your first loop will scan through the entire file. You start from the top again the second time you open it.

      If your logfile consistently contains three line entries, you could loop on the date regex and then readline() in the next two lines, parse all three at the same time, then loop back up again. The pointer will follow your place in the file and you'll be right at the next timestamp entry.

      open file; while(<file>) { my $line1 = $_; my $line2 = readline(<file>); my $line3 = readline(<file>); #handle $line1, $line2, $line3 all at once then #loop up for the next entry }