Search code examples
regexperlparsingloggingfilehandler

Perl - Parse blocks from text file


First, I apologize if you feel this is a duplicate. I looked around and found some very similar questions, but I either got lost or it wasn't quite what I think I need and therefore couldn't come up with a proper implementation.

QUESTION:

So I have a txt file that contains entries made by another script (I can edit the format for how these entries are generated if you can suggest a better way to format them):

SR4 Pool2
11/5/2012 13:45
----------
Beginning Wifi_Main().

SR4 Pool2
11/8/2012 8:45
----------
This message is a
multiline message.

SR4 Pool4
11/5/2012 14:45
----------
Beginning Wifi_Main().

SR5 Pool2
11/5/2012 13:48
----------
Beginning Wifi_Main().

And I made a perl script to parse the file:

#!C:\xampp-portable\perl\bin\perl.exe

use strict;
use warnings;
#use Dumper;

use CGI 'param','header';
use Template;
#use Config::Simple;

#Config::Simple->import_from('config.ini', \%cfg);

my $cgh = CGI->new;
my $logs = {};
my $key;

print "Content-type: text/html\n\n"; 

open LOG, "logs/Pool2.txt" or die $!;


while ( my $line = <LOG> ) {
    chomp($line);

}

print $logs;

close LOG;

My goal is to have a hash in the end that looks like this:

$logs = {
    SR4 => {
           Pool2 => {
                {
                    time => '11/5/2012 13:45',
                    msg  => 'Beginning Wifi_NDIS_Main().',
                },
                {
                    time => '11/8/2012 8:45',
                    msg  => 'This message is a multiline message.',
                },
           },
           Pool4 => {
                {
                    time => '11/5/2012 13:45',
                    msg  => 'Beginning Wifi_NDIS_Main().',
                },
           },
    },
    SR5 => {
           Pool2 => {
                {
                    time => '11/5/2012 13:45',
                    msg  => 'Beginning Wifi_NDIS_Main().',
                },
           },
    },

};

What would be the best way of going about this? Should I change the formatting of the generated logs to make it easier on myself? If you need anymore info, just ask. Thank you in advanced. :)


Solution

  • The format makes no sense. You used a hash at the third level, but you didn't specify keys for the values. I'm assuming it should be an array.

    my %logs;
    {
       local $/ = "";  # "Paragraph mode"
       while (<>) {
          my @lines = split /\n/;
          my ($x, $y) = split ' ', $lines[0];
          my $time = $lines[1];
          my $msg = join ' ', @lines[3..$#lines];
          push @{ $logs{$x}{$y} }, {
             time => $time,
             msg  => $msg,
          };
       }
    }
    

    Should I change the formatting of the generated logs

    Your time stamps appear to be ambiguous. In most time zones, an hour of the year is repeated.