use warnings; use strict; use Data::Dumper; my %data; while () { my ($id, @cols) = split; for my $i (0 .. $#cols) { my $type = ($i % 2) ? 'odd' : 'even'; push @{ $data{$id}{$type} } , $cols[$i]; } } print Dumper(\%data); __DATA__ a 1 2 3 4 5 6 b 9 8 7 6 5 4 #### $VAR1 = { 'a' => { 'even' => [ '1', '3', '5' ], 'odd' => [ '2', '4', '6' ] }, 'b' => { 'even' => [ '9', '7', '5' ], 'odd' => [ '8', '6', '4' ] } };