每第n行bash的平均值

时间:2014-12-07 19:31:11

标签: bash awk sed

我不知道如何制定问题,但现在是。

我有一个12/24/36/48行的长文件。

文件看起来像这样。

0 413
1 388
2 272
3 289
4 42
5 45
6 423
7 522
8 949
9 984
10 371
11 990
0 412
1 370
2 254
3 255
4 42
5 58
6 391
7 546
8 938
9 985
10 381
11 992

现在我想要做的是平均所有以0开头的行...所以例如413 + 412/2为0行,然后每行以1开头等等......直到11.所以输出只有12行,平均每第n行。

我真的很挣扎。我知道如何从一个数字开始唤醒每一行,但在那里得到一点但令人困惑。

3 个答案:

答案 0 :(得分:3)

awk '$1 == 0{c++;r+=$2}END{print r/c}' file
412.5

随意改善其他线路......

答案 1 :(得分:3)

awk '{sum[$1]=sum[$1] + $2; nr[$1]++} END {for (a in sum) {print a, sum[a]/nr[a]}}' file

保留第一个字段索引的第二个字段的运行总和。还要计算您看到的每个第一个字段的数量。然后遍历所有看到的字段并打印出字段和平均值。

如果您想按顺序输出,可以输入sort或使用END块中的数字循环(如果您提前了解最小值/最大值)。您还可以将最大值保留在主操作块中并使用它,但这更简单。

答案 2 :(得分:1)

Bash提供了一个简单的解决方案(更新以保持每个索引的个别计数为0 .. 11)。提供了一个额外的更新,设置了数组的整数属性,允许在算术运算符中更简洁地增加值:

#!/bin/bash

[ -n "$1" -a -f "$1" ] || {     # test filename provided & is readable
    printf "\n Error: invalid input. Usage:  %s <input_file>\n\n" "${0//*\//}"
    exit 1
}

declare -ai cnt      # count of how many times 0..11 encountered
declare -ai sum      # array holding running total of each 0 .. 11

while read -r idx val || [ -n "$val" ]; do      # read each line
    ((sum[idx]+=val))                           # keep sum of each 0 .. 11
    ((cnt[idx]++))                              # keep cnt of each 0 .. 11
done <"$1"

## for each element in the array, compute average and print (using bc for division)
printf "\nThe sum and averages of each line index are:\n\n"
for ((i=0; i<"${#sum[@]}"; i++)); do
    printf "  %4s  %8s / %-3s = %s\n" "$i" "${sum[i]}" "${cnt[i]}" "$(printf "%.3f" $(printf "scale=4;${sum[i]}/${cnt[i]}\n" | bc) )"
done

exit 0

<强>输出:

$ bash avgnthln.sh dat/avgln.dat

The sums and averages of each line index are:

     0       825 / 2   = 412.500
     1       758 / 2   = 379.000
     2       526 / 2   = 263.000
     3       544 / 2   = 272.000
     4        84 / 2   = 42.000
     5       103 / 2   = 51.500
     6       814 / 2   = 407.000
     7      1068 / 2   = 534.000
     8      1887 / 2   = 943.500
     9      1969 / 2   = 984.500
    10       752 / 2   = 376.000
    11      1982 / 2   = 991.000