#!perl
use strict;
use warnings;
my @cols =([0,6], [7,9], [16,7], [23,9], [32,8], [40,7], [47,5]);
#my @fieldwidths = (6, 9, 7, 9, 8, 7, 5);
my @arr;
my %h;
my @headers;
while (my $line = <DATA>) {
chomp $line;
my @data = map {trim($_)} parsefixed($line, @cols);
if ($. == 1) {
@headers = @data;
next;
}
@h{@headers} = @data;
push @arr, { %h };
}
for my $href (@arr) {
for my $h (@headers) {
print qq($h => $href->{$h}\n);
}
print "\n";
}
sub parsefixed {
# Parse a line of fixed-width data into an array based on @fieldwidths.
# @fieldwidths may be a flat list with just widths, e.g.
# (6, 9, 7, 9, 8, 7, 5)
# or a list of array refs with [start,len] elems, e.g.
# ([0,6], [7,9], [16,7], [23,9], [32,8], [40,7], [47,5])
my ($line, @fieldwidths) = @_;
#is this a flat list or a list of array refs?
my $isref = ref($fieldwidths[0]);
my @data;
my $start = 0;
my $len;
for (my $i=0; $i<@fieldwidths; $i++) {
if ($isref) {
($start, $len) = @{$fieldwidths[$i]};
} else {
$len = $fieldwidths[$i];
}
$data[$i] = substr($line, $start, $len);
$start += $len unless $isref;
}
return @data;
}
sub trim {
#Trim leading/trailing whitespace;
local $_ = shift;
s/^\s+//;
s/\s+$//;
$_;
}
__DATA__
Server Location BkUp Date time mbytes files
serv1 Atl yes 01/22/05 10:01 569333 5621
serv2 Chi no 23:00 3218 112
serv3 LA yes 01/22/05 34233 1231