in reply to recomendations needed for type of data structure

Looks like an array of hashes to me. Something like this (you can finish it if you use it):

use strict; my $hash; my $trap; my @data; while (<DATA>) { chomp; next if ($_ =~ /^\s*$/); if ($_ =~ /^Date:\s+(.+)$/) { push(@data, $hash) if (defined($hash)); $hash = {DATE => $1}; } if ($_ =~ /^SServer:\s+(.+)$/) { $hash->{SSERVER} = $1; } elsif ($_ =~ /^Device:\s+(.+)$/) { $hash->{DEVICE} = $1; } elsif ($_ =~ /^CString:\s+(.+)$/) { $hash->{CSTRING} = $1; } elsif ($_ =~ /^Port:\s+(.+)$/) { $hash->{PORT} = $1; } elsif ($_ =~ /^SNMP Traps Generated:/) { $hash->{TRAPS} = {TRAP_LIST => []}; } elsif ($_ =~ /^\s+Generic:\s+(.+)$/) { $hash->{TRAPS}->{GENERIC} = $1; } elsif ($_ =~ /^\s+Specific:\s+(.+)$/) { $hash->{TRAPS}->{SPECIFIC} = $1; } elsif ($_ =~ /^\s+Varbind:\s+(.+)$/) { $trap = {VARBIND => $1}; } elsif ($_ =~ /^\s+Type:\s+(.+)$/) { $trap->{TYPE} = $1; } elsif ($_ =~ /^\s+Data:\s+(.+)$/) { $trap->{DATA} = $1; push(@{$hash->{TRAPS}->{TRAP_LIST}}, $trap); } } push(@data, $hash) if (defined($hash)); my ($item, $key, $value); foreach $item (@data) { while (($key, $value) = each %$item) { print "$key => $value\n"; } print "\n"; } __DATA__ Date: Mon Feb 17 13:14:19 2003 SServer: formula3 Device: 111.222.123.124 CString: public Port: 162 SNMP Traps Generated: Trap OID: 1.3.6.1.4 Generic: 2 Specific: 0 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 10 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 20 Varbind: 1.3.6.1.2.1.2.2.1.7 Type: 2 Data: 20 Varbind: 1.3.6.1.2.1.2.2.1.8 Type: 2 Data: 30 Date: Mon Feb 17 13:14:22 2003 SServer: formula3 Device: 111.164.121.125 CString: public Port: 162 SNMP Traps Generated: Trap OID: 1.3.6.1.4 Generic: 3 Specific: 0 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 12 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 20

Replies are listed 'Best First'.
Re: Re: recomendations needed for type of data structure
by Anonymous Monk on Feb 17, 2003 at 19:16 UTC
    Thanks,
    That' swhat I had in mind.
    Just one question,
    Do you know why the array for the Traps isn't printing out properly?
    It's printing out the array reference instead
    Thanks
      This is because the array of traps is stored as a reference to an anonymous array in one of the keys (TRAP_LIST) of the anonymous hash in the TRAPS key of the %$hash. This means that when you try to print the keys and values of the %{$hash->{TRAPS}} hash, you get the stringified array reference. To solve this you could add a special case to the output loop which prints the contents of the array.
      # this handles ARRAYs and HASHes # you may want to use Data::Dumper for debugging however # the final code for processing the data structure will # also be less generic than this code. if (ref $value eq 'ARRAY') { print "$key => (@$value)\n"; } elsif (ref $value eq 'HASH') { print "$key => (%$value)\n"; } else print "$key => $value\n"; }

      --
      integral, resident of freenode's #perl
      
        Thank you Integral
        One last question,

        What would the syntax be if I wanted to simply print out?:

        Varbind: 1.3.6.1.2.1.2.2.1.1
        Thanks again, I'm slowly piecing this all together.

        Exactly ... that's part of what needs finishing. My laziness got the best of my hubris. 8-)

Re2: recomendations needed for type of data structure
by dragonchild (Archbishop) on Feb 18, 2003 at 17:56 UTC
    Looks real good. A few style comments, if you will.

    If you're using $_, you can just say if (/blahblah/) { instead of if ($_ =~ /blahblah/) {. $_ is the default 'it' ... use it as such.

    If it wasn't for the traps thing, you could write everything as:

    while (<DATA>) { chomp; next unless /^(\S+):\s+(.+)\s*$/; my ($key, $val) = (uc $1, $2); if ($key eq 'DATE') { push @data, $hash if defined $hash; $hash = {}; } $hash->{$key} = $val; }
    But, because of the 'SNMP Traps Generated' string, that doesn't work.

    But, can we make it work?

    use strict; my $hash = undef; my $trap = undef; my @data = (); while (<DATA>) { chomp; next unless /^\s*(\S+):\s+(.+)\s*$/o || /^\s*Trap (\S+):\s+(.+)\s*$/o || /^\s*SNMP (\S+) Generated:\s*$/o; my ($key, $val) = (uc $1, $2); if ($key eq 'DATE') { if (defined $hash) { if (defined $trap) { push @{$hash->{TRAPS}{TRAP_LIST}}, $trap; $trap = undef; } push @data, $hash if defined $hash; } $hash = {}; } elsif ($key eq 'TRAPS') { $hash->{TRAPS} = { TRAP_LIST => [] }; $trap = {}; next; } if ($key eq 'GENERIC' || $key eq 'SPECIFIC' || $key eq 'OID') { $hash->{TRAPS}{$key} = $val; } elsif (defined $trap) { $trap->{$key} = $val; if ($key eq 'DATA') { push @{$hash->{TRAPS}{TRAP_LIST}}, $trap; $trap = {}; } } else { $hash->{$key} = $val; } } if (defined $hash) { if (defined $trap) { push @{$hash->{TRAPS}{TRAP_LIST}}, $trap; $trap = undef; } push @data, $hash if defined $hash; } use Data::Dumper; print Data::Dumper->Dump([\@data]); __DATA__ Date: Mon Feb 17 13:14:19 2003 SServer: formula3 Device: 111.222.123.124 CString: public Port: 162 SNMP Traps Generated: Trap OID: 1.3.6.1.4 Generic: 2 Specific: 0 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 10 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 20 Varbind: 1.3.6.1.2.1.2.2.1.7 Type: 2 Data: 20 Varbind: 1.3.6.1.2.1.2.2.1.8 Type: 2 Data: 30 Date: Mon Feb 17 13:14:22 2003 SServer: formula3 Device: 111.164.121.125 CString: public Port: 162 SNMP Traps Generated: Trap OID: 1.3.6.1.4 Generic: 3 Specific: 0 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 12 Varbind: 1.3.6.1.2.1.2.2.1.1 Type: 2 Data: 20
    Why do it this way? If the data adds new things to track, it's easier to handle them. Plus, this way is quicker. While that's often not a big issue, what if this script is to be run every 15 minutes on a huge server? It does no good if the script takes 16 minutes to run ...

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.