完成分析后,我得到了一个包含许多列和行的表。另外,随着新表的写入,行/列的数量可能会有所不同,因此我无法预测每行将有多少行。每行在第一列中都有一个索引,但是这些索引可以在表中重复。所以我想要的是一种grep / awk / bash方式,以相同的索引检索所有这些行,并对所有列求和,以得到总和仅为一行。 作为说明:
表
index,sampleA,sampleB,sampleC
nana,22,12,4
baba,47,4,5
nana,1,5,9
nana,7,5,8
解析后
index,sampleA,sampleB,sampleC
nana,30,22,21
baba,47,4,5
如果您能帮助我,我将非常感激。 非常感谢。
答案 0 :(得分:0)
有点long,但是这样的事情会做:
awk -F"," 'BEGIN{OFS=FS} NR==1{print $0; next} NR>1{sampleA[$1]+=$2; sampleB[$1]+=$3; sampleC[$1]+=$4}END{for (sample in sampleA){print sample, sampleA[sample], sampleB[sample], sampleC[sample]}}' yourfile
说明:
-F","
分隔每行BEGIN{OFS=FS}
NR==1{print $0; next}
NR>1{sampleA[$1]+=$2; sampleB[$1]+=$3; sampleC[$1]+=$4}
中的值END{for (sample in sampleA){print sample, sampleA[sample], sampleB[sample], sampleC[sample]}}
答案 1 :(得分:0)
您没有指定外壳,但是如果您喜欢使用ksh(93l +),那也可以解决问题。
尽管如此,该脚本还是有一些假设:
每一列总是有一个值
#!/bin/ksh
# CSV to input as first argument, CSV to ouput as second argument
InputCSV=$1
OutputCSV=$2
typeset -A Index
while read line; do
lineArray=(${line//,/ })
# Assume that the first column is always named "index", but you can modify this
if [[ ${lineArray[0]} == "index" ]]; then
titleArray=(${line//,/ })
continue
fi
for ((i=1;i<${#lineArray[*]};i++)); do
if [[ -z ${Index[${lineArray[0]}][${titleArray[$i]}]} ]]; then
Index[${lineArray[0]}]+=( [${titleArray[$i]}]=${lineArray[$i]} )
else
Index[${lineArray[0]}][${titleArray[$i]}]=$(( ${Index[${lineArray[0]}][${titleArray[$i]}]} + ${lineArray[$i]} ))
fi
done
done < $InputCSV
exec 3>$OutputCSV
titleBar=${titleArray[0]}
for ((i=1;i<${#titleArray[*]};i++)); do
titleBar+=",${titleArray[$i]}"
done
print $titleBar >&3
for j in ${!Index[@]}; do
outLine=$j
for ((i=1;i<${#titleArray[*]};i++)); do
outLine+=",${Index[$j][${titleArray[$i]}]}"
done
print $outLine >&3
done
exec 3>&-