我正在尝试用Bash编写一个循环来打印文件中每一列的总和。这些列由制表符分隔。到目前为止,我得到的是:
cols() {
count=$(grep -c $'\t' $1)
for n in $(seq 1 $count) ;do
cat $FILE | awk '{sum+=$1} END{print "sum=",sum}'
done
}但这只打印出第一列的总和。如何才能对每一列执行此操作?
发布于 2017-01-20 06:29:00
您的方法完成了这项工作,但在某种程度上有些夸张:您先计算列数,然后对文件执行cat操作并调用awk,而awk本身就可以完成所有这些工作:
awk -F"\t" '{for(i=1; i<=NF; i++) sum[i]+=$i} END {for (i in sum) print i, sum[i]}' file这利用了存储一行包含的字段数量的NF (这就是您对count=$(grep -c $'\t' $1)所做的工作)。然后,只需遍历字段并对数组中的每个元素求和,其中sum[i]包含列i的总和。最后,它遍历结果并写入它的值。
为什么你的方法不是对一个给定的专栏进行求和?因为当你说:
for n in $(seq 1 $count) ;do
cat $FILE | awk '{sum+=$1} END{print "sum=",sum}'
done您总是使用$1作为求和的元素。相反,您应该使用以下内容将值$n传递给awk:
awk -v col="$n" '{sum+=$col} END{print "sum=",sum}' $FILE # no need to cat $FILE发布于 2017-01-20 08:36:49
如果你想要一个只有bash内置的解决方案,这是可行的:
declare -i i l
declare -ai la sa=()
while read -d$'\t' -ra la; do
for ((l=${#la[@]}, i=0; i<l; sa[i]+=la[i], ++i)); do :; done
done < file
(IFS=$'\t'; echo "${sa[*]}")它的性能应该是不错的,但比awk之类的要慢得多。
https://stackoverflow.com/questions/41752870
复制相似问题