Reading CSV file as many hash-es
Given the following CSV file how can we read it line-by-line?
There are two main ways, read each line as an array, or read each line as a hash, where the keys are taken from the first row of the file.
The sample input file:
examples/data/planets.csv
Planet name,Distance (AU),Mass Mercury,0.4,0.055 Venus,0.7,0.815 Earth,1,1 Mars,1.5,0.107 Ceres,2.77,0.00015 Jupiter,5.2,318 Saturn,9.5,95 Uranus,19.6,14 Neptune,30,17 Pluto,39,0.00218 Charon,39,0.000254
Read each CSV line as an array
examples/read_planets_array.pl
#!/usr/bin/perl use strict; use warnings; use Text::CSV; use Data::Dumper qw(Dumper); my $file = $ARGV[0] or die "Need to get CSV file on the command line\n"; read_as_array($file); sub read_as_array { my ($filename) = @_; my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1, sep_char => ',' # not really needed as this is the default }); open(my $data, '<:encoding(utf8)', $filename) or die "Could not open '$filename' $!\n"; while (my $row = $csv->getline($data)) { print(Dumper $row); } close $data; }
Each row is a reference to an array holding the values of the given row. Note, the first row is the header.
The dumped output will look like this:
examples/read_planets_array.out
$VAR1 = [ 'Planet name', 'Distance (AU)', 'Mass' ]; $VAR1 = [ 'Mercury', '0.4', '0.055' ]; $VAR1 = [ 'Venus', '0.7', '0.815' ]; $VAR1 = [ 'Earth', '1', '1' ]; $VAR1 = [ 'Mars', '1.5', '0.107' ]; $VAR1 = [ 'Ceres', '2.77', '0.00015' ]; $VAR1 = [ 'Jupiter', '5.2', '318' ]; $VAR1 = [ 'Saturn', '9.5', '95' ]; $VAR1 = [ 'Uranus', '19.6', '14' ]; $VAR1 = [ 'Neptune', '30', '17' ]; $VAR1 = [ 'Pluto', '39', '0.00218' ]; $VAR1 = [ 'Charon', '39', '0.000254' ];
Read each CSV line as a hash
In this case we read in the first line and set it as the list of columns. Then when we read in the subsequent rows from the CSV file, the method will return a hash for each row.
examples/read_planets_hash.pl
#!/usr/bin/perl use strict; use warnings; use Text::CSV; use Data::Dumper qw(Dumper); my $file = $ARGV[0] or die "Need to get CSV file on the command line\n"; read_as_hash($file); sub read_as_hash { my ($filename) = @_; my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1, sep_char => ',' # not really needed as this is the default }); open(my $data, '<:encoding(utf8)', $filename) or die "Could not open '$filename' $!\n"; my $header = $csv->getline($data); $csv->column_names($header); while (my $row = $csv->getline_hr($data)) { print(Dumper $row); } close $data; }
examples/read_planets_hash.out
$VAR1 = { 'Distance (AU)' => '0.4', 'Mass' => '0.055', 'Planet name' => 'Mercury' }; $VAR1 = { 'Planet name' => 'Venus', 'Mass' => '0.815', 'Distance (AU)' => '0.7' }; $VAR1 = { 'Distance (AU)' => '1', 'Planet name' => 'Earth', 'Mass' => '1' }; $VAR1 = { 'Distance (AU)' => '1.5', 'Mass' => '0.107', 'Planet name' => 'Mars' }; $VAR1 = { 'Distance (AU)' => '2.77', 'Mass' => '0.00015', 'Planet name' => 'Ceres' }; $VAR1 = { 'Distance (AU)' => '5.2', 'Planet name' => 'Jupiter', 'Mass' => '318' }; $VAR1 = { 'Planet name' => 'Saturn', 'Mass' => '95', 'Distance (AU)' => '9.5' }; $VAR1 = { 'Mass' => '14', 'Planet name' => 'Uranus', 'Distance (AU)' => '19.6' }; $VAR1 = { 'Distance (AU)' => '30', 'Mass' => '17', 'Planet name' => 'Neptune' }; $VAR1 = { 'Planet name' => 'Pluto', 'Mass' => '0.00218', 'Distance (AU)' => '39' }; $VAR1 = { 'Distance (AU)' => '39', 'Planet name' => 'Charon', 'Mass' => '0.000254' };
Published on 2020-07-25