http://www.perlmonks.org?node_id=795381

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

I'm trying to parse CLI output but occasionally have a column with no data. Any regex tricks I can use to capture that? Here is my code:
use strict; use warnings; use Data::Dumper; my $string = ""; my @data = (); while(<DATA>) { push @data, $_; $_ =~ s/\n/ /g; $string .= $_; } my %hash = (); foreach ( @data ) { chomp; my @array = split (/\s+/, $_); print Dumper(@array); print "\n"; } __DATA__ Port Alias Oper Admin Speed Duplex Type (truncated) Status Status (bps) ------------ ---------------- -------- ------- ------ ------- -------- +---------- vlan.0.4094 up up other host.0.1 up up 10.0M other ge.1.1 down up 10.0M half 10-t + rj45 ge.1.2 down up 10.0M half 10-t + rj45 ge.1.3 down up 10.0M half 10-t + rj45 ge.1.4 down up 10.0M half 10-t + rj45 ge.1.5 down up 10.0M half 10-t + rj45

Replies are listed 'Best First'.
Re: regex help
by moritz (Cardinal) on Sep 15, 2009 at 13:34 UTC
    Since it looks like fixed-size data, I recommend looking at the example in perlpacktut, it does something very similar.
    Perl 6 - links to (nearly) everything that is Perl 6.
      This does look like fixed width data (its from a telnet or ssh right?)

      If it were me I'd also use a fixed width approach. Small suggestion however, add in a check that the last character of each 'field' that you extract must be space char. While this doesn't guarantee that you'll catch data from one field running into the next, it does increase your chances.
Re: regex help
by dHarry (Abbot) on Sep 15, 2009 at 13:44 UTC

    Why not use one of the available CLI modules?

Re: regex help
by grizzley (Chaplain) on Sep 16, 2009 at 07:04 UTC

    Little shorter version (sorry, couldn't resist my perlgolfer soul...) - maybe you will find it useful.

    #!perl -l use strict; use warnings; use Data::Dumper; my @data = <DATA>; my $string = join" ", @data; for(@data) { my @array = split; print Dumper(@array); } __DATA__ Port Alias Oper Admin Speed Duplex Type (truncated) Status Status (bps) ------------ ---------------- -------- ------- ------ ------- -------- +---------- vlan.0.4094 up up other host.0.1 up up 10.0M other ge.1.1 down up 10.0M half 10-t + rj45 ge.1.2 down up 10.0M half 10-t + rj45 ge.1.3 down up 10.0M half 10-t + rj45 ge.1.4 down up 10.0M half 10-t + rj45 ge.1.5 down up 10.0M half 10-t + rj45

    But I do not know where you get empty column. I have run it, but I don't see any empty variables...

Re: regex help
by ph0enix (Friar) on Sep 16, 2009 at 13:20 UTC

    Try this if you need to use regexp ;-) Following code will create two-dimensional array from your data. Header is skipped and line with dashes (delimiter between header and data) is used for regexp pattern creation.

    #!/usr/bin/perl -w # use strict; use warnings; use Data::Dumper; my @data; my $data = 0; my $line; my @size; my $re; while ($line = <DATA>) { chomp $line; # remove EOL next if ($line =~ /^\s*$/); # skip empty lines if any if ($data) { # process data using regexp push @data, [ map { s/(^\s+|\s+$)//; $_ } ($line =~ /$ +re/) ]; } elsif ($line =~ /^-/) { # create regexp from pattern $data = 1; # end of header @size = map { length } split(/\s+/, $line); pop @size; $re = '^' . join(' ', map { "(.{$_})" } @size) . ' + (.*)'; } } print Data::Dumper::Dumper(\@data); __DATA__ Port Alias Oper Admin Speed Duplex Type (truncated) Status Status (bps) ------------ ---------------- -------- ------- ------ ------- -------- +---------- vlan.0.4094 up up other host.0.1 up up 10.0M other ge.1.1 down up 10.0M half 10-t + rj45 ge.1.2 down up 10.0M half 10-t + rj45 ge.1.3 down up 10.0M half 10-t + rj45 ge.1.4 down up 10.0M half 10-t + rj45 ge.1.5 down up 10.0M half 10-t + rj45