Here is my version, reads from __DATA__ if there is no 'Data.txt'
#!/usr/bin/perl ---
use strict;
use warnings;
use autodie;
Main(@ARGV);
exit(0);
sub Main {
my $input = shift @_ || 'Data.txt';
my $output = shift @_ || 'Output.txt';
eval {
open my ($infh), '<', $input;
open my ($outfh), '>', $output;
ReadThenPrint( $infh, $outfh );
1;
} or ReadThenPrint( \*DATA, \*STDOUT ); ## demo
} ## end sub Main
sub ReadThenPrint {
my ( $infh, $outfh ) = @_;
my @rows;
my $colid = 0;
while (<$infh>) {
next if /^\s+$/;
chomp;
if (/^#id(\d+)/) {
$colid = $1 - 1;
next;
}
my ( $rowid, $num ) = split /\s+/, $_, 2;
push @{ $rows[$rowid][$colid] }, $num;
} ## end while (<$infh>)
#~ use DDS;
#~ Dump( \@rows );
print join( "\t", "#", map { 1 + $_ } 0 .. $colid ), "\n";
for my $rowid ( 0 .. $#rows ) {
my @cols = @{ $rows[$rowid] };
use List::Util qw' max ';
my $max = max map { $#$_ } @cols;
for my $maxid ( 0 .. $max ) {
print "$rowid\t";
for my $col (@cols) {
print $col->[$maxid] if $col and ref $col and defined $col->[$
+maxid];
print "\t";
}
print "\n";
} ## end for my $maxid ( 0 .. $max)
} ## end for my $rowid ( 0 .. $#rows)
} ## end sub ReadThenPrint
__DATA__
#id1
1 90
2 80
3 70
#id2
1 70
2 40
2 40
3 20
4 5
#id3
0 0
0 0
0 0
output seems to be what you want (also included debugging
DDS Dump )
$ARRAY1 = [
[
( undef ) x 2,
[
( 0 ) x 3
]
],
[
[ 90 ],
[ 70 ]
],
[
[ 80 ],
[
( 40 ) x 2
]
],
[
[ 70 ],
[ 20 ]
],
[
undef,
[ 5 ]
]
];
# 1 2 3
0 0
0 0
0 0
1 90 70
2 80 40
2 40
3 70 20
4 5