use strict; use Text::CSV; use Data::Dumper; my (%report,@headers); my $csv = Text::CSV->new(); while() { die unless $csv->parse($_); if ($. == 1) { @headers = $csv->fields(); $report{headers} = \@headers; } else { my @row = $csv->fields(); push @{$report{data}}, {map{$headers[$_]=>$row[$_]} (0..$#row)}; } } print Dumper \%report; __DATA__ foo,bar 333,aaa 444,bbb 555,ccc