nidhi has asked for the wisdom of the Perl Monks concerning the following question:

Hi all
I am trying to match a similar set of lines from a config file and store the results in a hash.

interface Port-channel31 description abc.xyz-conf no ip address load-interval 60 switchport switchport trunk encapsulation dot1q switchport trunk allowed vlan 15-17,30,35
I did get help from perlmonks earlier but now I need to use this code in a tool called alterpoint which has some crazy ways of using perl.

The code i was using :
local $/ = "interface "; while(<IN>) { my ($key) = /description\s+ ([^\"][^\s]+)/x; next if $key =~ /^\s*$/; my ($value) = /switchport trunk allowed vlan\s*(.*)/; $hash2{$key} = $val ; }
where <IN> is the opened file. I need to get away with the IRS $/ as I dont think it works in alterpoint and also, I might have to do the pattern matching in the following manner :
my @lines = split(/^/, $config); # Iterate over the lines. foreach my $line (@lines) { if ($line =~ /description\s+ ([^\"][^\s]+)/x) { my ($key) = "$_"; next if ($line =~ /^\s*$/) } if ($line =~ /switchport trunk allowed vlan\s*(.*)/) { my ($value) = "$_"; } $hash1{$key} = $value ; }
or something...desperately need help!!
thanks

Replies are listed 'Best First'.
Re: Another way to match multi-lines from config.
by johngg (Canon) on Sep 10, 2007 at 21:15 UTC
    I'm not quite sure from your post exactly what it is you want to do. I'm guessing that there are multiple "interface" descriptions in the configuration file and you need to extract one key/value pair from each. Processing line by line is probably not a good idea as you could get an interface with a good description line but a bad switchport line followed by the converse, thus ending up with a key from the one associated with a value from the other.

    As long as the configuration file was of manageable size I would read the whole file into a string and then split it into individual interfaces using a look-ahead pattern. Then I would iterate over the interfaces extracting both key and value using a single regex and adding them to the hash.

    use strict; use warnings; use Data::Dumper; my $data = do { local $/; <DATA>; }; my @interfaces = split m{(?=interface)}, $data; my $rxExtract = qr {(?xms) description\s+ (\S+) .*? switchport\strunk\sallowed\svlan\s* ([^\n]+) }; my %hash; foreach my $interface ( @interfaces ) { $hash{$1} = $2 if $interface =~ $rxExtract } print Data::Dumper->Dumpxs([\%hash], [q{*hash}]); __END__ interface Port-channel31 description abc.xyz-conf no ip address load-interval 60 switchport switchport trunk encapsulation dot1q switchport trunk allowed vlan 15-17,30,35 interface Port-channel32 description def.uvw-conf no ip address load-interval 55 switchport switchport trunk encapsulation dot1q switchport trunk allowed vlan 12-15,31-38 interface Port-channel35 description ghi.rst-conf no ip address load-interval 75 switchport switchport trunk encapsulation dot1q switchport trunk allowed vlan 21-26,44,47,51

    Here's the Data::Dumper output.

    %hash = ( 'ghi.rst-conf' => '21-26,44,47,51', 'def.uvw-conf' => '12-15,31-38', 'abc.xyz-conf' => '15-17,30,35' );

    As I said, I'm not sure if this is what you want but, hopefully, it will give you some help.

    Cheers,

    JohnGG

Re: Another way to match multi-lines from config.
by FunkyMonk (Bishop) on Sep 10, 2007 at 21:42 UTC
    • Read the file line-by-line, and look for "description" and "switchport" lines, extracting your key and value if you find them.
    • Reset key and value if the line is an "interface" line.
    • Store the key/value pair in a hash when you have both
    use Data::Dumper; my ( $key, $value, %hash2 ); while ( <DATA> ) { $key = $value = undef and next; if /^interface /; $key = $1 if /description\s+ ([^\"][^\s]+)/x; $value = $1 if /switchport trunk allowed vlan\s*(.*)/; next unless $key && $value; $hash2{$key} = $value; $key = $value = undef; } print Dumper \%hash2;

    Using johngg's test data gives:

    $VAR1 = { 'ghi.rst-conf' => '21-26,44,47,51', 'def.uvw-conf' => '12-15,31-38', 'abc.xyz-conf' => '15-17,30,35' };

      Thanks a ton monks..you made my day..which so far has gone scratching my head and pulling my hair !!!