我有以下格式的文件
id_1,1,0,2,3,lable1
id_2,3,2,2,1,lable1
id_3,5,1,7,6,lable1
我想每一列的总和(我有超过300列)
9,3,11,10,lable1
我怎么能做到这一点使用bash。 我试着用什么描述在这里 ,但没有奏效。
我有以下格式的文件
id_1,1,0,2,3,lable1
id_2,3,2,2,1,lable1
id_3,5,1,7,6,lable1
我想每一列的总和(我有超过300列)
9,3,11,10,lable1
我怎么能做到这一点使用bash。 我试着用什么描述在这里 ,但没有奏效。
如果总计将需要在最后一列的标签进行分组,你可以试试这个:
awk -F, '
{
L[$NF]
for(i=2; i<NF; i++) T[$NF,i]+=$i
}
END{
for(i in L){
s=i
for(j=NF-1; j>1; j--) s=T[i,j] FS s
print s
}
}
' file
如果在最后一列的标签进行排序,那么你可以尝试没有数组和节省内存:
awk -F, '
function labelsum(){
s=p
for(i=NF-1; i>1; i--) s=T[i] FS s
print s
split(x,T)
}
p!=$NF{
if(p) labelsum()
p=$NF
}
{
for(i=2; i<NF; i++) T[i]+=$i
}
END {
labelsum()
}
' file
使用awk
:
$ awk -F, '{for (i=2;i<NF;i++)a[i]+=$i}END{for (i=2;i<NF;i++) printf a[i]",";print $NF}' file
9,3,11,10,lable1
这将打印每一列的总和(从i = 2 .. I = N-1)以逗号分隔的文件,随后从最后一行的最后一列的值(即lable1)。
这里有一个Perl的一行代码:
<file perl -lanF, -E 'for ( 0 .. $#F ) { $sums{ $_ } += $F[ $_ ]; } END { say join ",", map { $sums{ $_ } } sort keys %sums; }'
它只会做算术,所以在你的例子中,第一和最后一栏为0。
这个版本将按照您的输出示例:
<file perl -lanF, -E 'for ( 1 .. $#F - 1 ) { $sums{ $_ } += $F[ $_ ]; } END { $sums{ $#F } = $F[ -1 ]; say join ",", map { $sums{ $_ } } sort keys %sums; }'
根据您链接的解决方案的修改版本:
#!/bin/bash
colnum=6
filename="temp"
for ((i=2;i<$colnum;++i))
do
sum=$(cut -d ',' -f $i $filename | paste -sd+ | bc)
echo -n $sum','
done
head -1 $filename | cut -d ',' -f $colnum
纯bash的解决方案:
#!/usr/bin/bash
while IFS=, read -a arr
do
for((i=1;i<${#arr[*]}-1;i++))
do
((farr[$i]=${farr[$i]}+${arr[$i]}))
done
farr[$i]=${arr[$i]}
done < file
(IFS=,;echo "${farr[*]}")