Bash在文件中汇总数字

时间:2016-06-14 11:28:05

标签: bash

我有一个看起来像这样的文件:

aaa 15
aaa 12
bbb 131
bbb 12
ccc 123
ddddd 1
ddddd 2
ddddd 3

我想像这样得到左侧每个独特元素的总和,并计算每个元素的总百分比:

aaa 27 - 9%
bbb 143 - 48%
ccc 123 - 41%
ddddd 6 - 2%

我如何在BASH中完成此任务?

3 个答案:

答案 0 :(得分:3)

由于我找不到任何正确的副本,我正在发布答案。随意报告一个好的,所以我将删除我的答案并关闭为重复。

awk '{count[$1]+=$2} END {for (i in count) print i, count[i]}' file

这将创建一个数组count[key]=value,用于跟踪给定键的值。最后,它遍历值并打印它们。

它返回:

aaa 27
ccc 123
bbb 143
ddddd 6

要显示百分比,只需跟踪总和并相应地划分:

awk '{tot+=$2; count[$1]+=$2} 
      END {for (i in count) 
           printf "%s %d - %d%%\n", i, count[i], (count[i]/tot)*100
      }' file

所以你可以得到:

aaa 27 - 9%
ccc 123 - 41%
bbb 143 - 47%
ddddd 6 - 2%

答案 1 :(得分:0)

由于你要求Bash,这里有一个Bash≥4解决方案(关联数组需要Bash≥4):

#!/bin/bash

declare -Ai sums

while read -r ref num; do
    # check that num is a valid number or continue
    [[ $num = +([[:digit:]]) ]] || continue
    sums[$ref]+=$(( 10#$num ))
done < file

for ref in "${!sums[@]}"; do
    printf '%s %d\n' "$ref" "${sums[$ref]}"
done

输出未排序;通过sort(或使用排序算法)对其进行排序。

所以现在你添加了百分比要求!我希望你不要再编辑这个问题,进一步添加更多东西......

一旦我们得到了关联数组sums,我们就可以求和:

sum=0
for x in "${sums[@]}"; do ((sum+=x)); done

并打印百分比:

for ref in "${!sums[@]}"; do
    printf '%s %d - %d%%\n' "$ref" "${sums[$ref]}" "$((100*${sums[$ref]}/sum))"
done

答案 2 :(得分:0)

bash 3的解决方案,没有关联数组:

while read key value
do
    keys=$(echo -e "$keys\n$key")
    var=data_$key
    (($var=${!var}+$value))
    ((total=total+$value))
done < input_file

unique=$(echo "${keys:1}" | sort -u)
while read key
do
    var=data_$key
    ((percentage=100*${!var} / total))
    echo "$key $percentage%"
done <<EOF
$unique
EOF

更改为使用间接变量引用,而不是更传统的eval