Summing up an array inside of awk?
Try this:
$ awk -F',' 'BEGIN{OFS="\t";print "Name","Sum1","Sum2"}
{print $1,$2+$3+$4,$5+$6+$7}' sample.csv
Name Sum1 Sum2
abc 6 15
de 15 14
xyz 14 17
There is no need for your bash loop, you can do everything in awk
. The -F
option allows you to define the input field separator, in this case ,
, so you don't need to explicitly split the line. Since awk
reads files line by line, you also don't need to read the file in bash
.
The BEGIN{}
block is executed before reading the first line and just prints the header and sets the output separator (OFS
) to a tab. Since the fields are already separated, all you need to do is sum up fields 2-4 and 5-7 and print them for each line.
Setting up $temp
First be sure that you've set up the $temp
variable properly:
$ temp="abc,1,2,3,4,5,6"
$ echo "$temp"
abc,1,2,3,4,5,6
Simple example
I used the following approach to do it:
$ echo "$temp" | tr ',' '\n' | grep -v abc | awk '{sum+=$1};END{print sum}'
21
Your example
Regarding your approach you forgot to print the arrays you accumulated with an END{...}
block:
$ echo "$temp" | awk '{split($0,a,","); name=a[1]
for(i=2;i<=4;i++) sum1+=a[i] ; for(i=5;i<=7;i++) sum2+=a[i] }
END{print sum1; print sum2}'
6
15
Saving for later
Awk doesn't have a method for injecting results back into the parent's shell from where it was called, so you'll have to get a bit crafty and save it's results to an array in Bash.
Example
$ myarr=($(echo "$temp" | awk '{split($0,a,","); name=a[1]
for(i=2;i<=4;i++) sum1+=a[i] ; for(i=5;i<=7;i++) sum2+=a[i] }
END{ print sum1; print sum2}'))
The above is doing this:
$ myarr=($(...awk command...))
This will result in your values from sum1
and sum2
being saved into array $myarr
.
Accessing the array $myarr
They're accessible like so:
$ echo "${myarr[@]}"
6 15
$ echo "${myarr[0]}"
6
$ echo "${myarr[1]}"
15
Bash
#!/usr/bin/env bash
printf "%-5s\t%s\t%s\n" Name Sum1 Sum2
while IFS=, read -a Arr
do
(( Grp1 = Arr[1] + Arr[2] + Arr[3] ))
(( Grp2 = Arr[4] + Arr[5] + Arr[6] ))
printf "%-5s\t%d\t%d\n" ${Arr[0]} $Grp1 $Grp2
done < input.txt
Output
root@ubuntu:~# bash parse.sh
Name Sum1 Sum2
abc 6 15
de 15 14
xyz 14 17
Thanks to @1_CR for arithmetic tricks for array element