I want to parse some reports from multiple devices, reports looks like this:
VR Destination Mac Age Static VLAN VID Port VR-Default 192.168.11.13 90:e2:ba:3c:95:c0 2 NO intra1 350 49 VR-Default 192.168.1.1 00:0e:a6:f7:b6:b5 0 NO main 602 1 VR-Default 192.168.1.2 00:0d:88:63:bf:d1 3 NO main 602 1 VR-Default 192.168.1.14 00:1c:f0:c7:d2:52 4 NO main 602 1 etc... Dynamic Entries : 19 Static Entries : 0 Pending Entries : 1 In Request : 3888802 In Response : 4531 and some more data... Rx Error : 0 Dup IP Addr : 0.0.0.0 and some more...
I need only vr, destination, mac, age, static, vlan, vid and port fields.
I can parse it using split
function and regexes, but split fails if one field (e.g. Age) is empty.
perldoc says I can use unpack
:
my $template = 'A13xA16xA18xA4xA7xA13xA5xA*';
for my $line ( split /\n/, $data ) {
chomp $line;
my ($vr, $destination, $mac, $age, $static, $vlan, $vid, $port) = unpack $template, $line;
...
}
But it dies on lines with length < 84. And I got to check string length every time (Or maybe using eval
on unpack? Is it better?). And again I got to use regexes or index
to find the end of main table and skip headers.
The code will looks like:
#!/usr/bin/perl
use strict;
use warnings;
my $arp = <<'ARP';
VR Destination Mac Age Static VLAN VID Port
VR-Default 192.168.11.13 90:e2:ba:3c:95:c0 2 NO intra1 350 49
VR-Default 192.168.1.1 00:0e:a6:f7:b6:b5 0 NO main 602 1
VR-Default 192.168.1.2 00:0d:88:63:bf:d1 3 NO main 602 1
VR-Default 192.168.1.14 00:1c:f0:c7:d2:52 4 NO main 602 1
Dynamic Entries : 19 Static Entries : 0
Pending Entries : 1
In Request : 3888802 In Response : 4531
Rx Error : 0 Dup IP Addr : 0.0.0.0
ARP
my $template = 'A13xA16xA18xA4xA7xA13xA5xA*';
for my $line ( split /\n/, $arp ) {
last if index( $line, 'Dynamic E' ) == 0;
next if length $line < 84;
chomp $line;
my ($vr, $destination, $mac, $age, $static, $vlan, $vid, $port) = unpack $template, $line;
next if $mac eq 'Mac';
print "$mac - $destination\n";
}
My question is: how would you parse this data? split, regexes, unpack, substr or something else?