CSV spreadsheet files are suitable for storing tabular data in a relatively portable way.

The CSV format is flexible but somewhat ill-defined.

For present purposes, authors may assume that the data fields contain no commas, backslashes, or quotation marks.



Task

Read a CSV file, change some values and save the changes back to a file.

For this task we will use the following CSV file:

C1,C2,C3,C4,C5
1,5,9,13,17
2,6,10,14,18
3,7,11,15,19
4,8,12,16,20

Suggestions


 Show how to add a column, headed 'SUM', of the sums of the rows.
 If possible, illustrate the use of built-in or standard functions, methods, or libraries, that handle generic CSV files.



#!/usr/bin/perl
use warnings;
use strict;
 
use List::Util 'sum';
 
my @header = split /,/, <>;
# Remove the newline.
chomp $header[-1];
 
my %column_number;
for my $i (0 .. $#header) {
    $column_number{$header[$i]} = $i;
}
my @rows   = map [ split /,/ ], <>;
chomp $_->[-1] for @rows;
 
# Add 1 to the numbers in the 2nd column:
$_->[1]++ for @rows;
 
# Add C1 into C4:
$_->[ $column_number{C4} ] += $_->[ $column_number{C1} ] for @rows;
 
# Add sums to both rows and columns.
push @header, 'Sum';
$column_number{Sum} = $#header;
 
push @$_, sum(@$_) for @rows;
push @rows, [
                map  {
                    my $col = $_;
                    sum(map $_->[ $column_number{$col} ], @rows);
                } @header
            ];
 
# Print the output.
print join(',' => @header), "\n";
print join(',' => @$_), "\n" for @rows;
 