我不知道如何制定问题,但现在是。
我有一个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行。
我真的很挣扎。我知道如何从一个数字开始唤醒每一行,但在那里得到一点但令人困惑。
答案 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