use Text::CSV 'csv'; my $aoh = csv ( in => 'input.csv', headers => 'auto' ); # Fetch the "patN" column names, in order. This works # for single digit "patN" names, as that was your # example. Multi-digit names will require a more complex # sort, left as an exercise to the reader. my @pats = sort grep /^pat\d+$/, keys %{$aoh->[0]}; my %sums; # Column sums. $sum{column} += $value; for my $row ($@aoa) { for (map { $row->{$_} } @pats) { # You are now iterating over every patN value, # in order. Perform your transformation } # Just an example. $sums{$_} += $row->{$_} for @pats; }