use strict; use warnings; my %hash; my %found; while (my $line = ) { chomp $line; next if ($line =~ m/^\s*$/); my @part = split /\s+/, $line; $found{$part[1]}++; $hash{$part[0]}{$part[1]} = $part[2]; } my @sets = sort keys %found; print join(q{ }, q{NAME}, @sets), qq{\n}; foreach my $k (sort keys %hash) { my @data; foreach my $l (@sets) { if (defined $hash{$k}{$l}) { push @data, $hash{$k}{$l}; } else { push @data, q{ }; } } print join(q{ }, $k, @data), qq{\n}; } __DATA__ AA SET1 0 AA SET2 1 AA SET3 0 BB SET1 0 BB SET3 0 CC SET1 2 CC SET2 3 #### NAME SET1 SET2 SET3 AA 0 1 0 BB 0 0 CC 2 3