use*_*293 6 shell scripting bash awk shell-script
我有以下一段代码:
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] }'
Run Code Online (Sandbox Code Playgroud)
此代码不起作用。这里 temp 是一个字符串类型:
abc,1,2,3,4,5,6
Run Code Online (Sandbox Code Playgroud)
实际上我正在解析文件中的数据。输入文件是这样的:
abc,1,2,3,4,5,6
de,3,5,7,8,4,2
xyz,6,5,3,7,8,2
Run Code Online (Sandbox Code Playgroud)
我正在阅读它
while read temp
do
#do something
done < sample.csv
Run Code Online (Sandbox Code Playgroud)
预期输出的形式为:
Name Sum1 Sum2
abc 6 15
de 15 14
xyz 14 17
Run Code Online (Sandbox Code Playgroud)
ter*_*don 11
尝试这个:
$ 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
Run Code Online (Sandbox Code Playgroud)
不需要你的 bash 循环,你可以在awk. 该-F选项允许您定义输入字段分隔符,在本例中为,,因此您无需显式拆分行。由于awk逐行读取文件,因此您也不需要在bash.
该BEGIN{}块在读取第一行之前执行,仅打印标题并将输出分隔符( OFS) 设置为制表符。由于字段已经分开,您需要做的就是总结字段 2-4 和 5-7 并为每一行打印它们。
首先确保您已$temp正确设置变量:
$ temp="abc,1,2,3,4,5,6"
$ echo "$temp"
abc,1,2,3,4,5,6
Run Code Online (Sandbox Code Playgroud)
我使用以下方法来做到这一点:
$ echo "$temp" | tr ',' '\n' | grep -v abc | awk '{sum+=$1};END{print sum}'
21
Run Code Online (Sandbox Code Playgroud)
关于您的方法,您忘记打印您使用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
Run Code Online (Sandbox Code Playgroud)
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}'))
Run Code Online (Sandbox Code Playgroud)
上面是这样做的:
$ myarr=($(...awk command...))
Run Code Online (Sandbox Code Playgroud)
这将导致您的值来自sum1并sum2保存到 array 中$myarr。
它们可以像这样访问:
$ echo "${myarr[@]}"
6 15
$ echo "${myarr[0]}"
6
$ echo "${myarr[1]}"
15
Run Code Online (Sandbox Code Playgroud)