我有以下代码:
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...))
这将导致您的值sum1
被sum2
保存到 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 提供数组元素的算术技巧