Need help modifying parse program.
awohld
created: 2006-03-04 12:00:25
I'm trying to parse these logfile records and I can't get the "Secondary Sector Informaton" data parse correctly. This is my program I made when I asked for Record Parsing Advice

Why is "Secondary Sector Information" and "Slot" showing up in the output and how can I get it out? No matter what I do, the match isn't working like I think it should.

Below the code is the acual output and the output I'm trying to get.
use strict;
use warnings;

local $/= "\n=";

while (my $line = )
{
print "\n------------------------------\n";
if ($line =~ m/Primary \(Reporting\) Cp\s*:\s*((?:(?!Set).)*)Set\s*:\s*((?:(?!Car).)*)Car\s*:\s*((?:(?!Ref).)*)/si)
{
    print "Cp:$1 - Set:$2 - Car:$3";
}

if ($line =~ m/Phase\s*:\s*((?:(?!Strength).)*)Strength\s*:\s*((?:(?!\n).)*)/si)
{
    print "\nPhase:$1 - Strength:$2\n";
}


while ($line =~ m/(?

Here is what my incorrect output looks like:
------------------------------
Cp:113   - Set:2  - Car:1
Phase:0x2fdf   - Strength:24
------------------------------
------------------------------
Cp:115   - Set:1  - Car:2
Phase:0x7d10   - Strength:31
Keep:1  Phase: 0x7d10  Strength: 31
Secondary Sector Information:
Slot 1:   Keep: 1    - offset:391    - Strength:27
Keep:1    - offset:325    - Strength:38
------------------------------


And it should look like this

------------------------------
Cp:113   - Set:2  - Car:1
Phase:0x2fdf   - Strength:24
------------------------------
------------------------------
Cp:115   - Set:1  - Car:2
Phase:0x7d10   - Strength:31
Keep:1  Phase: 0x7d10  Strength: 31
Keep:1    - Pn_offset:391    - Strength:27
Keep:1    - Pn_offset:325    - Strength:38
------------------------------
Re: Need help modifying parse program.
created: 2006-03-04 13:26:12
I'm not even going to try reading through those regex. Why not make things simpler and do something more like:
use strict;
use warnings;

my %d;
while () {
    if (m/^Primary \(Reporting\) Cp:/) {
        ($d{'cp'}) = m/Cp: (\d+)/s;
        ($d{'set'}) = m/Set: (\d+)/s;
        ($d{'car'}) = m/Car: (\d+)/s;
        print "Cp:$d{'cp'} - Set:$d{'set'} - Car:$d{'car'}\n";
    }
    elsif (m/^Missing P:/) {
        ($d{'keep'}) = m/Keep: (\d+)/s;
        ($d{'phase'}) = m/Phase: (\w+)/s;
        ($d{'strength'}) = m/Strength: (\d+)/s;    
        print "Phase:$d{'phase'} - Strength:$d{'strength'}\n";
    }
    elsif (m/Secondary Sector Information:/) {
        print "Keep:$d{'keep'} - Phase:$d{'phase'} - Strength:$d{'strength'}\n";
    }
    elsif (m/^Slot/) {
        ($d{'keep'}) = m/Keep: (\d+)/s;
        ($d{'offset'}) = m/Offset: (\w+)/s;
        ($d{'strength'}) = m/Strength: (\d+)/s;    
        print "Keep:$d{'keep'} - Pn_offset:$d{'phase'} - Strength:$d{'strength'}\n";
    }
    elsif (m/^={68}/) {
        %d = ();
        print '-'x30, "\n";
    }
}
print '-'x30, "\n";


__DATA__
====================================================================
Record: 9851329   Version:  2   Timestamp: Sat Feb 11 22:39:43 2006
Primary (Reporting) Cp: 113  Set: 2 Car: 1  Ref: yes  Event:   9922
Missing P:  Keep: 1  Phase: 0x2fdf  Strength: 24
Secondary Sector Information:
====================================================================
Record: 9851330   Version:  2   Timestamp: Sat Feb 11 22:39:43 2006
Primary (Reporting) Cp: 115  Set: 1 Car: 2  Ref: yes  Event:   9923
Missing P:  Keep: 1  Phase: 0x7d10  Strength: 31
Secondary Sector Information:
Slot 1:   Keep: 1   offset: 391   Strength: 27   Ref: no
Slot 2:   Keep: 1   offset: 325   Strength: 38   Ref: no
Re: Need help modifying parse program.
created: 2006-03-04 13:44:46
You have got the "Secondary Sector Informaton" and the "Slot" in there because you're matching everything from "Keep:" to "offset" in your inner while loop, so the first match of $1 in the second block becomes
Phase: 0x7d10  Strength: 31
Secondary Sector Information:
Slot 1:   Keep: 1    -
I would replace the last while loop with something simpler like
map {
    if ( $_ =~ m/Keep:\s*(\d+)\s*(Phase|offset):\s*([xabcdef\d]+)\s*Strength:\s*(\d+)/ ) {
        print "Keep:${1} - ${2}:${3} - Strength:${4}\n";
    }
} split /\r\n|\n/, $line;
Re: Need help modifying parse program.
created: 2006-03-04 14:48:46

I strongly recommend using the /x flag with your large regexen to make them more readable and maintainable. It can help code readability to put the regex into a variable too so the flow logic can be seen easily. Consider:

use strict;
use warnings;

my $regex = qr|
  Primary\s\(Reporting\)\s
  Cp\s*:\s*((?:(?!Set).)*)  # Now we can see what's happening
  Set\s*:\s*((?:(?!Car).)*) # but why are the look aheads needed?
  Car\s*:\s*((?:(?!Ref).)*)
  |six;

while () {
  next if $_ !~ $regex;
  print;
}
__DATA__
====================================================================
Record: 9851329   Version:  2   Timestamp: Sat Feb 11 22:39:43 2006
Primary (Reporting) Cp: 113  Set: 2 Car: 1  Ref: yes  Event:   9922
Missing P:  Keep: 1  Phase: 0x2fdf  Strength: 24
Secondary Sector Information:
====================================================================
Record: 9851330   Version:  2   Timestamp: Sat Feb 11 22:39:43 2006
Primary (Reporting) Cp: 115  Set: 1 Car: 2  Ref: yes  Event:   9923
Missing P:  Keep: 1  Phase: 0x7d10  Strength: 31
Secondary Sector Information:
Slot 1:   Keep: 1   offset: 391   Strength: 27   Ref: no
Slot 2:   Keep: 1   offset: 325   Strength: 38   Ref: no

Prints:

Primary (Reporting) Cp: 113  Set: 2 Car: 1  Ref: yes  Event:   9922
Primary (Reporting) Cp: 115  Set: 1 Car: 2  Ref: yes  Event:   9923

Note, this is not an attempt to solve you immediate problem - others have done that. It is simply a demonstration of a couple of coding tips.


DWIM is Perl's answer to Gödel

perlmonks.org content © perlmonks.org and awohld, GrandFather, matze, TedPride

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03