in reply to MultiLine Tables into Variables

You're going to have to do two passes if it's a huge file (as in huge = too big for memory). The first pass does most of the work:

The temp file looks something like:

BD3101|bananaswiithapples.gif|\breakfast\fruits\tree\|2007-03-06 14:02 +:31.000000 TP4223|chocolatecaramelfudge.gif|\sweet\desserts\hersheys\|2006-02-28 +21:16:41.000000 EO2123|tofuwithpeas.gif|\organic\vegetables\legumes\|2007-07-16 13:55: +06.000000

The second pass processes this temp file and produces the formatted output:

BD3101 bananaswiithapples.gif \breakfast\fruits\tree\ 2007-03- +06 14:02:31.000000 TP4223 chocolatecaramelfudge.gif \sweet\desserts\hersheys\ 2006-02- +28 21:16:41.000000 EO2123 tofuwithpeas.gif \organic\vegetables\legumes\ 2007-07- +16 13:55:06.000000

The code that follows doesn't use files at at all (I'll leave that to you - it's trivial) and produces the output above:

my ( @in, @out, @temp_file ); my @lengths = (0) x 4; pass1(); pass2(); sub pass1 { while ( <DATA> ) { my @in = unpack "A9A10A9A*", $_; if ( $in[0] ) { write_to_temp( @out ) if $out[0]; @out = @in; next; } $out[$_] .= $in[$_] for 0 .. 3; } write_to_temp( @out ); } sub pass2 { my $format = join " ", ( map "%-${_}s", @lengths ), "\n"; for ( @temp_file ) { chomp; my @f = split /\|/; printf $format, @f; } } sub write_to_temp { s/\s+/ /g, s/^\s+//, s/\s+$// for $_[3]; length $_[$_] > $lengths[$_] and $lengths[$_] = length $_[$_] for 0 .. 3; push @temp_file, join( "|", @_ ) . "\n"; }

PS I've assumed BrowserUk's comment about mistyped sample data to be true.