while (<>) { s/\r?\n//; # strip line endings # get field numbers and field description if (/\s{2,3}(\d+)\. (.+)/) { my ($number, $text) = ($1,$2); $number--; # since first element of an array is 0, not 1 # if this field denotes string length, store it if ($text =~ /string length/i) { push(@lengths, $number); } # remember field number and text (only if not previously seen) $names{$number} = $text unless $names{$number}; next; # nothing else to do for this line. } # now process the one line of data, if at hand if (/^====>/) { # Record Starter, right? # split line at whitespace my @array = split; # for all length indicators, concatenate # subsequent array elements into one # complain if the size doesn't fit for my $index (@lengths) { my $length = $array[$index]; my $string; my $counter = 1; while (length $string < $length) { # join array elements with space to rebuild the field $string = join " ", $string, $array[$index + $counter]; warn "length mismatch for $string: $length <=> ".length $string,"\n" if length $string > $length + 1; } # weed out concatenated elements from array splice @array, $index + 1, $counter; } # done, output the fields for (sort {$a <=> $b} keys %names) { print "$names{$_}: $array[$_]\n"; } } }