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'
        };