I'm successfully parsing a cisco config file, and grabbing the sections of config between each marker (cisco uses the ! symbol) using a multi line regex of:
/(search string)/i .. /^!/
My code looks like:
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my (@results, @data) ;
#Test data to simulate a while loop on a file-handle running through a config file.
@data = (
"vlan 81" ,
" name Vlan 81 test1" ,
"!" ,
"vlan 82" ,
" name Vlan 82 test2" ,
"!" ,
"vlan 83" ,
" name Vlan 83 test3" ,
"!"
);
foreach ( @data ) {
if ( /vlan/i .. /^!/ ) {
push (@results , $_) ;
}
}
print Dumper ( @results ) . "\n" ;
exit;
It works really well, but I want to push the results into a hash, with each section of code being an anonymous array, so the results would look something like:
%Vlan -> [Vlan 81, name Vlan 81 test1] , [Vlan 82, name Vlan 82 test2] , [Vlan 83, name Vlan 83 test3]
But I can't work out how to do it, my code matches per line between the search string and the marker and I just end up rebuilding the results into another array, line by line.
Any help is much appreciated.
Cheers,
Andy
I'm not sure what you mean about a hash, as the contents you describe are just a list of anonymous arrays. There are no keys so you can only produce an array. If you can explain which part of the data is to be the key then we can go for a hash.
The use warnings
pragma is preferable to the -w
shebang modifier as it is more flexible and can be negated.
The range operator ..
may be cute but you mustn't squeeze it into use wherever possible.
Setting the input separator to "!\n"
will allow you to read in all related lines at once, which can then be pushed onto your array.
The code looks like this
use strict;
use warnings;
use Data::Dumper;
my @Vlan;
$/ = "!\n";
while (<DATA>) {
chomp;
push @Vlan, [split /[\r\n]+/];
}
print Data::Dumper->Dump([\@Vlan], ['*Vlan']);
__DATA__
vlan 81
name Vlan 81 test1
!
vlan 82
name Vlan 82 test2
!
vlan 83
name Vlan 83 test3
!
output
@Vlan = (
[
'vlan 81',
'name Vlan 81 test1'
],
[
'vlan 82',
'name Vlan 82 test2'
],
[
'vlan 83',
'name Vlan 83 test3'
]
);
EDIT
If the key of the hash is always the first line of the record set, then this program produces a hash as you requested
use strict;
use warnings;
use Data::Dumper;
my %Vlan;
$/ = "!\n";
while (<DATA>) {
chomp;
my ($k, $v) = split /[\r\n]+/;
$Vlan{$k} = $v;
}
print Data::Dumper->Dump([\%Vlan], ['*Vlan']);
__DATA__
vlan 81
name Vlan 81 test1
!
vlan 82
name Vlan 82 test2
!
vlan 83
name Vlan 83 test3
!
output
%Vlan = (
'vlan 81' => 'name Vlan 81 test1',
'vlan 83' => 'name Vlan 83 test3',
'vlan 82' => 'name Vlan 82 test2'
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With