http://www.perlmonks.org?node_id=932517


in reply to I need help joining tab-delimited files/tables!

The trick here is to use a hash of arrays to store the table entries. Consider:

use warnings; use strict; my $table1 = <<TABLE; ID value Aa 22 Bb 28 Cc 32 Dd 50 TABLE my $table2 = <<TABLE; ID value Aa 34 Cc 112 Dd 77 Ee 89 Kk 124 TABLE my $table3 = <<TABLE; ID value Bb 75 Cc 91 Dd 132 TABLE my $table4 = <<TABLE; ID value Aa 66 Cc 94 Ee 213 Gg 250 TABLE my %values; my $tableIndex = 0; for my $inFileVar (\$table1, \$table2, \$table3, \$table4) { open my $inFile, '<', $inFileVar or die "Can't open $inFileVar: $! +\n"; while (<$inFile>) { chomp; my ($id, $value) = split; next if $id eq 'ID'; $values{$id}[$tableIndex] = $value; } ++$tableIndex; } for my $id (sort keys %values) { print "$id"; print ' ', $values{$id}[$_] || 0 for 0 .. $tableIndex - 1; print "\n"; }

Prints:

Aa 22 34 0 66 Bb 28 0 75 0 Cc 32 112 91 94 Dd 50 77 132 0 Ee 0 89 0 213 Gg 0 0 0 250 Kk 0 124 0 0

Note that the variables in the first for loop are used as in memory files so the open provides a file handle that uses the contents of each variable as the file contents. This technique is handy for avoiding extra files in sample code. Your real code can simply substitute a list of file names for the list of variable references.

True laziness is hard work

Replies are listed 'Best First'.
Re^2: I need help joining tab-delimited files/tables!
by daptal (Acolyte) on Oct 19, 2011 at 22:19 UTC
    An alternative solution to the above would be something like this
    my @files = ('file1','file2','file3','file4'); # use a glob if you prefer my %hash; foreach my $file_name (@files){ open my $fh, '<',$file_name || die "$!"; while (<$fh>){ chomp; next if (/^\s*$/); my ($id,$val) = split /\t/; $hash{$id}{$file_name} = $val; } close $fh; } foreach my $id (sort keys %hash){ print "$id\t"; print $hash{$id}{$_} ? "$hash{$id}{$_}\t" : "0\t" foreach (@f +iles); print "\n"; }
      Your "open" statement has the "Operator precedence" problem described in die on file open.

                  "XML is like violence: if it doesn't solve your problem, use more."