需要求和或求均值文件为tab分割,第一行为列名,第一列为有重复名的数据,其他列为数值,示例:
使用awk求和:
awk -v ty=sum 'BEGIN{FS=OFS="\t"}NR==1{print $0;ncol=NF}NR>1{if($1 in che){dup[$1]+=1;for(i=1;i<NF+1;i++){num[$1,i]=$i+num[$1,i]}}else{che[$1]=$0;for(i=1;i<NF+1;i++){num[$1,i]=$i}}}END{for(i in che){if(i in dup){if(ty=="sum"){printf i"\t";for(j=2;j<NF;j++){printf num[i,j]"\t"}print num[i,NF]}else if(ty=="mean"){dup[i]+=1;printf i"\t";for(j=2;j<NF;j++){printf num[i,j]/dup[i]"\t"}print num[i,NF]/dup[i]}}else{print che[i]}}}' 111
结果:
求均值也是相同的命令,只是ty改成mean,结果:
思路是在读取时用二维数组定位每一个值,再判断行名是否重复,重复的相加,记录相加次数;读取结束后判断,如果是无重复的则直接输出,节省时间和算力;如果是有重复的,再判断参数是sum还是mean,如果是mean就将sum值除以相加次数即可
awk -v ty=sum 'BEGIN{FS=OFS="\t"}NR==1{
print $0;ncol=NF}NR>1{
if($1 in che){
dup[$1]+=1;
for(i=1;i<NF+1;i++){
num[$1,i]=$i+num[$1,i]
}
}else{
che[$1]=$0;
for(i=1;i<NF+1;i++){
num[$1,i]=$i
}
}
}END{
for(i in che){
if(i in dup){
if(ty=="sum"){
printf i"\t";
for(j=2;j<NF;j++){
printf num[i,j]"\t"}print num[i,NF]
}else if(ty=="mean"){
dup[i]+=1;
printf i"\t";
for(j=2;j<NF;j++){
printf num[i,j]/dup[i]"\t"}print num[i,NF]/dup[i]
}
}else{
print che[i]
}
}
}'