对 awk 内的数组求和?

对 awk 内的数组求和?

我有以下代码:

sum1=
sum2=    
declare -a a
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] }'

该代码不起作用。这里 temp 是一个字符串类型:

abc,1,2,3,4,5,6

实际上我正在解析文件中的数据。输入文件如下:

abc,1,2,3,4,5,6
de,3,5,7,8,4,2
xyz,6,5,3,7,8,2

我正在使用它来阅读

while  read temp
do
 #do something
done < sample.csv

预期输出的形式为:

Name   Sum1  Sum2
abc      6    15
de      15    14
xyz     14    17 

答案1

尝试这个:

$ 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

不需要 bash 循环,您可以在awk.该-F选项允许您定义输入字段分隔符(在本例中为 ),,因此您无需显式拆分行。由于awk逐行读取文件,因此您也不需要读取bash.

BEGIN{}块在读取第一行之前执行,仅打印标题并设置输出分隔符( OFS) 到选项卡。由于字段已经分开,您所需要做的就是对字段 2-4 和 5-7 求和并为每行打印它们。

答案2

设置 $temp

首先确保您已$temp正确设置变量:

$ temp="abc,1,2,3,4,5,6"
$ echo "$temp"
abc,1,2,3,4,5,6

简单的例子

我使用以下方法来做到这一点:

$ echo "$temp" | tr ',' '\n' | grep -v abc | awk '{sum+=$1};END{print sum}'
21

你的例子

关于您的方法,您忘记打印用块累积的数组END{...}

$ 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

保存以供日后使用

Awk 没有将结果从调用它的地方注入回父级 shell 的方法,因此您必须使用一些技巧并将其结果保存到 Bash 中的数组中。

例子

$ 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}'))

上面是这样做的:

$ myarr=($(...awk command...))

这将导致您的值sum1sum2保存到 array 中$myarr

访问数组 $myarr

它们可以像这样访问:

$ echo "${myarr[@]}"
6 15

$ echo "${myarr[0]}"
6

$ echo "${myarr[1]}"
15

答案3

重击

#!/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

输出

root@ubuntu:~# bash  parse.sh
Name    Sum1    Sum2
abc     6       15
de      15      14
xyz     14      17

感谢 @1_CR 提供数组元素的算术技巧

相关内容