平均每第n行bash

问题描述:

我不知道如何制定问题,但在这里。平均每第n行bash

我有一个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 +2分之412为0线,则每行开头的1 ...等,直到11.所以输出将只有12条线,每条线的平均值为。

我真的很挣扎。我知道如何awk以数字开头的每一行,但会有点混乱。

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

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

如果您希望输出顺序为sort或在END块中使用数字循环(如果您知道最小/最大值)。你也可以在主动作块中保留最大值并使用它,但这很简单。

+1

THX工作的,我排序它然后与只是排序-g ..这就是我需要的。 – SaKer 2014-12-07 19:53:02

+0

我总是对你的'awk'解决方案摇头,并且想,“男人,我必须深入awk ......”。简洁,高效。我喜欢。 – 2014-12-07 20:01:37

+1

@ DavidC.Rankin当我看着EdMorton和fedorqui的答案时,我感觉一样。 – 2014-12-07 20:17:39

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

随意改善,这是其他行...

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 
+0

为了安全起见,我会保持一个按指数计数,但很好地完成。 – 2014-12-07 20:00:01

+0

是的,我发现这比在整个文件中假设你有整套更好。我会调整它。 – 2014-12-07 20:08:58