A slightly more extensible version with a complete dispatch array implementation matched to named capture regular expressions for the columns. (Use the same data file.)
#!perl
my $table_spliter = qr/^Mod\s*((Ports)|(Sub))/;
my @columns = (
[ qw( SLOT PORTAS DESC Model Sw ) ],
[ qw( Slot Desc Model Sw Hw Status ) ],
);
my @column_spliters = (
qr/
(?<$columns[0]->[0]>.{4})
(?<$columns[0]->[1]>.{6})
(?<$columns[0]->[2]>.{39})
(?<$columns[0]->[3]>.{19})
(?<$columns[0]->[4]>.{10,11})
/sxm,
qr/
(?<$columns[1]->[0]>.{5})
(?<$columns[1]->[1]>.{28})
(?<$columns[1]->[2]>.{19})
(?<$columns[1]->[3]>.{12})
(?<$columns[1]->[4]>.{8})
(?<$columns[1]->[5]>.{2,7})
/sxm,
);
my @pre_strings = ( '', '<> ' );
my $position;
while(<DATA>){
my $line = $_;
chomp $line;
my @types = $line =~ $table_spliter;
for my $x ( 1..$#types ){
if( $types[$x] ){
$position = $x - 1;#Handle '|' in $table_spliter
last;
}
}
$line =~ $column_spliters[$position];
my %line_hash = %+;
if(
!@types and
( keys %line_hash ) and
( %line_hash )[1] !~ /^-/ ){
for my $item ( @{$columns[$position]} ){
my $value = $line_hash{$item};
$value =~ s/^\s*(.*?)\s*$/$1/;
print $pre_strings[$position] .
$item . ": " . $value . "\n";
}
}else{
print "Header/Other: $line\n";
}
}
close(DATA);
Update: removed un-needed variable declarations, still requires perl 5.10 or higher