Mugen
Mugen

Reputation: 9085

Bash: Sum fields of a line

I have a file with the following format:

a 1 2 3 4
b 7 8
c 120

I want it to be parsed into:

a 10
b 15
c 120

I know this can be easily done with awk, but I'm not familiar with the syntax and can't get it to work for me.

Thanks for any help

Upvotes: 2

Views: 234

Answers (4)

glenn jackman
glenn jackman

Reputation: 246744

Here's a tricky way to use a subshell, positional parameters and IFS. Works with various amounts of whitespace between the fields.

while read label numbers; do 
    echo $label $(set -- $numbers; IFS=+; bc <<< "$*")
done < filename

This works because the shell expands "$*" into a single string of the positional parameters joined by the first char of $IFS (documentation)

Upvotes: 0

peteches
peteches

Reputation: 3609

ok simple awk primer:

awk '{ for (i=2;i<=NF;i++) { total+=$i }; print $1,total; total=0 }' file

NF is an internal variable that is reset on each line and is equal to the number of fields on that line so

for (i=2;i<=NF;i++) starts a for loop starting at 2

total+=$i means the var total has the value of the i'th field added to it. and is performed for each iteration of the loop above.

print $1,total prints the 1st field followed by the contents of OFS variable (space by default) then the total for that line.

total=0 resets the totals var ready for the next iteration.

all of the above is done on each line of input.

For more info see grymoires intro here

Upvotes: 5

Guru
Guru

Reputation: 16974

A pure bash solution:

$ while read f1 f2
> do
>   echo $f1 $((${f2// /+}))
> done < file

On running it, got:

a 10
b 15
c 120

The first field is read into variable f1 and the rest of the fields are i f2. In variable f2 , spaces are replaced in place with + and evaluated.

Upvotes: 3

P.P
P.P

Reputation: 121357

Start from column two and add them:

 awk '{tot=0; for(i=2;i<$NF;i++) tot+=$i; print $1, tot;}' file

Upvotes: 3

Related Questions