7 added 805 characters in body
source | link

1;2;3 4;5;6 7;8;9

1;2;3   4;5;6   7;8;9

1;2;3 4;5;6 7;8;9

1;2;3   4;5;6   7;8;9
6 added 805 characters in body
source | link

If tab separation isn't suitable for your needs, you can use sprintf to do the formatting:

my $format = '%12s';
print map { sprintf($format, $_) } ( $id, @header),"\n";
foreach my $key ( sort keys %stuff ) {   
   print map { sprintf($format, $_) } ( $key, map { join ";", @{$stuff{$key}{$_}}} @header),"\n";
}

We make some use of map here, which I appreciate isn't exactly an obvious thing.

What it does is take a list, and apply a transformation to each element. So - in the above example:

print join ("\y", map { join ";", @$_ } ([1,2,3],[4,5,6],[7,8,9]) )

Will generate:

1;2;3 4;5;6 7;8;9

The map operation is saying 'join each subarray on ;' and then return that as a list... that we can then join with a tab. That's basically what the above is doing.

If tab separation isn't suitable for your needs, you can use sprintf to do the formatting:

my $format = '%12s';
print map { sprintf($format, $_) } ( $id, @header),"\n";
foreach my $key ( sort keys %stuff ) {   
   print map { sprintf($format, $_) } ( $key, map { join ";", @{$stuff{$key}{$_}}} @header),"\n";
}

We make some use of map here, which I appreciate isn't exactly an obvious thing.

What it does is take a list, and apply a transformation to each element. So - in the above example:

print join ("\y", map { join ";", @$_ } ([1,2,3],[4,5,6],[7,8,9]) )

Will generate:

1;2;3 4;5;6 7;8;9

The map operation is saying 'join each subarray on ;' and then return that as a list... that we can then join with a tab. That's basically what the above is doing.

5 added 805 characters in body
source | link

Perl can do this handily, using a hash:

#!/usr/bin/env perl

use strict;
use warnings;

my %stuff;
my @header = split ' ', <>;

#read in the data to "stuff"
while ( <> ) { 
   my ( $key, $value ) = split; 
   push ( @{$stuff{$key}}, $value ); 
}

print join ("\t", @header ),"\n"; 
foreach my $key ( sort keys %stuff ) {
   print $key, "\t", join ";", @{$stuff{$key}},"\n";
}

Output:

A   B
123 fvv;kjf;ccd;
567 abc;abc;
879 ttt;

Where you went wrong? Honestly, I would suggest it's in trying to compress it all into a one liner. That is - in my opinion - really bad practice. At best, it promotes inscrutable code that's hard to follow.

The above could be condensed down, but it really pays to do it longhand first.  

In order to support multiple columns, then you start to hit a slight bit of a nuisance with column widths.

This works, but produces output that indentation isn't neatly aligned:

#!/usr/bin/env perl

use strict;
use warnings;

my %stuff; 

my ( $id, @header ) = split ' ', <>;

while ( <> ) { 
   my ( $key, @values ) = split; 
   my %row;
   @row{@header} = @values; 
   push ( @{$stuff{$key}{$_}}, $row{$_} ) for keys %row;
}

print join ( "\t", $id, @header),"\n";
foreach my $key ( sort keys %stuff ) {
   print join ("\t", $key, map { join ";", @{$stuff{$key}{$_}}} @header), "\n";
}

Output of:

A   B   C
123 fvv;kjf;ccd ggg;ggg;att
567 abc;abc gst;hgt
879 ttt tyt

Perl can do this handily, using a hash:

#!/usr/bin/env perl

use strict;
use warnings;

my %stuff;
my @header = split ' ', <>;

#read in the data to "stuff"
while ( <> ) { 
   my ( $key, $value ) = split; 
   push ( @{$stuff{$key}}, $value ); 
}

print join ("\t", @header ),"\n"; 
foreach my $key ( sort keys %stuff ) {
   print $key, "\t", join ";", @{$stuff{$key}},"\n";
}

Output:

A   B
123 fvv;kjf;ccd;
567 abc;abc;
879 ttt;

Where you went wrong? Honestly, I would suggest it's in trying to compress it all into a one liner. That is - in my opinion - really bad practice. At best, it promotes inscrutable code that's hard to follow.

The above could be condensed down, but it really pays to do it longhand first.  

Perl can do this handily, using a hash:

#!/usr/bin/env perl

use strict;
use warnings;

my %stuff;
my @header = split ' ', <>;

#read in the data to "stuff"
while ( <> ) { 
   my ( $key, $value ) = split; 
   push ( @{$stuff{$key}}, $value ); 
}

print join ("\t", @header ),"\n"; 
foreach my $key ( sort keys %stuff ) {
   print $key, "\t", join ";", @{$stuff{$key}},"\n";
}

Output:

A   B
123 fvv;kjf;ccd;
567 abc;abc;
879 ttt;

Where you went wrong? Honestly, I would suggest it's in trying to compress it all into a one liner. That is - in my opinion - really bad practice. At best, it promotes inscrutable code that's hard to follow.

The above could be condensed down, but it really pays to do it longhand first.

In order to support multiple columns, then you start to hit a slight bit of a nuisance with column widths.

This works, but produces output that indentation isn't neatly aligned:

#!/usr/bin/env perl

use strict;
use warnings;

my %stuff; 

my ( $id, @header ) = split ' ', <>;

while ( <> ) { 
   my ( $key, @values ) = split; 
   my %row;
   @row{@header} = @values; 
   push ( @{$stuff{$key}{$_}}, $row{$_} ) for keys %row;
}

print join ( "\t", $id, @header),"\n";
foreach my $key ( sort keys %stuff ) {
   print join ("\t", $key, map { join ";", @{$stuff{$key}{$_}}} @header), "\n";
}

Output of:

A   B   C
123 fvv;kjf;ccd ggg;ggg;att
567 abc;abc gst;hgt
879 ttt tyt
4 Rollback to Revision 1
source | link
3 added 230 characters in body
source | link
2 I was about to post pretty much the same thing as a one-liner, so I added it here instead
source | link
1
source | link