This is fairly easy to do in Perl, even as a one-liner:
perl -MList::Util=sum -anE 'if (1 == $.) { say join(q{ }, @F, q{FullYear}) } else { say join(q{ }, @F, sum(@F[2..13])) }' «YOUR-FILE»
Explanation:
-MList::Util=sum loads the List::Util module and imports the sum function. This is the same as use List::Util qw(sum).
-n tells Perl to process the input file line-by-line, running the script for each line. (Actually redundant, as the next option implicitly turns this on). -a turns on autosplit mode, so we get an array @F with one entry per field. -E means we're going to provide a script as a command-line argument, using current Perl features (for "say" in this case).
Full details for those options can be found in the perlrun manpage/podfile.
Then, here is the script, with spacing added, and comments explaining:
if (1 == $.) { # $. is the line number. Line 1 is header line.
say join(' ', @F, q{FullYear}); # print out the heder + FullYear
}
else {
# print out rows + sum of columns 2..13. Remember Perl counts from 0 in arrays,
# so column 2 is the 3rd column (the number for January).
say join(' ', @F, sum(@F[2..13]));
}
BTW: You can ask Perl to help understand one-liners (at least ones you trust — this is not safe with untrusted scripts) with -MO=Deparse, which gives output like this:
command:
perl -MO=Deparse -MList::Util=sum -anE 'if (1 == $.) { say join(q{ }, @F, q{FullYear}) } else { say join(q{ }, @F, sum(@F[2..13])) }' t-file
output:
use List::Util (split(/,/, 'sum', 0));
use feature 'current_sub', 'bitwise', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
LINE: while (defined($_ = readline ARGV)) {
our @F = split(' ', $_, 0);
if (1 == $.) {
say join(' ', @F, 'FullYear');
}
else {
say join(' ', @F, &sum(@F[2..13]));
}
}
-e syntax OK
So you can see the List::Util load, the -n going line-by-line, and -a adding the split.
awkscript not working as expected?printfto specify the format in which you want the results to be printed. It's also helpful in your example input to use data which demonstrates the problem you're having. By default it's probably using exponential notation; if you want fixed-point notation you can do something likeprintf( "%5.10f", $6 )to get five and ten places of output before and after the decimal point, respectively.