use warnings; use strict; use Data::Dumper; my @AoA = ( [qw/single cell values/], [qw/are really easy/], ["but multiline stilton", "these cells is", "aren't suck great"], [qw/back to life/], [qw/back to reality with more cells/]); #This is where the garbage begins... my @new_rows; my $width = 3; foreach my $row (@AoA) { my @cells = @$row; my @foo = map { split /\n/ } @cells; my $new_row = 0; my $new_row_idx = 0; for(my $idx = 0; $idx<$#foo; $idx++) { if(($idx % $width) == 0) { $new_row++; $new_row_idx = 0; } $new_rows[$new_row][$new_row_idx] = $foo[$idx]; $new_row_idx++; } } print Dumper(\@new_rows);