对每行的所有值求和,并使用 Bash 将结果写入新列中



我有一个大文件(许多列(,通常看起来像:

Gene,A,B,C
Gnai3,2,3,4
P53,5,6,7
H19,4,4,4

我想对数据框的每一行求和并将其添加为新列,如下所示:

Gene,A,B,C,total
Gnai3,2,3,4,9
P53,5,6,7,18
H19,4,4,4,12

我尝试了awk -F, '{sum=0; for(i=1; i<=NF; i++) sum += $i; print sum}'但后来我无法为总数制作新列。

任何帮助将不胜感激。

你能试试下面的吗?

awk '
BEGIN{
FS=OFS=","
}
FNR==1{
print $0,"total"
next
}
{
for(j=2;j<=NF;j++) 
$(NF+1)+=$j
}
$1=$1
}
1
' Input_file


第二个解决方案:根据OP的注释添加解决方案以仅打印第一列和总和。

BEGIN{
FS=OFS=","
}
FNR==1{
print $0,"total"
next
}
{
for(j=2;j<=NF;j++) 
sum+=$j
}
print $1,sum
sum=""
}
' Input_file

可以在这里使用 perl:

perl -MList::Util=sum0 -F, -lane '
print $_, ",", ($. == 1 ? "total" : sum0( @F[1..$#F] ));
' file

要添加新列,只需增加列数并为新列分配一个值:

NF++; $NF=sum

做:

awk -v OFS=, -F, 'NR>1{sum=0; for(i=1; i<=NF; i++) sum += $i; NF++; $NF=sum } 1'

仅使用 bash:

#!/bin/bash
while read -r row; do
sum=
if [[ $row =~ (,[0-9]+)+ ]]; then
numlist=${BASH_REMATCH[0]}
sum=,$((${numlist//,/+}))
fi
echo "$row$sum"
done < datafile

这里有一些关于数据文件中的行的假设:要求和的数值字段是非负整数,第一个字段不是数值字段(即使它是数值字段,它也不会参与总和(。此外,数值字段是连续的,也就是说,两个数值字段之间没有非数值字段。而且,总和不会溢出。

最新更新