值的总和大于多个矩阵中每列的平均值

时间:2017-01-14 21:13:04

标签: bash awk

我在作为参数给出的文件中有一些矩阵。我需要找到每列的平均值,并且只列出列中大于或等于列平均值的数字。

例如:

f1:

10 20 30
5  8
9

f2

1 1 2 2 3
5
6   6
1 1 1 1 1

f3

1 2 3 4 5
6 7 8 4 10
8
10 9 8 7 6

,输出应为

f1: 19 20 30
f2: 11 6 2 2 3
f3: 18 16 16 7 10

你运行这样的程序:

MS.1 f1 f2 f3

到目前为止,我得到了这个:

#!/bin/awk -f
BEGIN {
    M=0
    M1=0
    counter=1
    fname=ARGV[1]
    printf fname":"
}

(fname==FILENAME) {
    split($0,A," ")
    for(i=1;i<=length(A);i++) {
        B[i]=B[i]+A[i]
        if(A[i]<=0||A[i]>=0)
            C[i]=C[i]+1
    }
    for(i=1;i<=length(B);i++) {
        if((C[i]<0||C[i]>0))
            D[i]=B[i]/C[i]
    }
    for(i=1;i<=length(A);i++) {
        if(A[i]>=D[i])
            E[i]=E[i]+" "+A[i]
    }
}

(fname!=FILENAME) {
    for(i=1;i<=length(E);i++) {
        printf " "E[i]
    }
    printf "\n"
    for(i=1;i<=length(B);i++) {
        B[i]=0
    }
    for(i=1;i<=length(C);i++) {
        C[i]=0
    }
    fname=FILENAME
    printf fname":"
}

END {
    for(i=1;i<=length(B);i++) {
        printf " "B[i]
    }
    printf "\n"
}

但它只适用于第一个文件,然后它会混乱。

我的输出是

f1: 19 20 30
f2: 30 26 31 1 1 1
f3: 24 16 16 11 16 0

我知道我遇到了所有阵列问题。

2 个答案:

答案 0 :(得分:1)

此处bashawk的组合将简化脚本

将其另存为script.sh

#!/bin/bash

for f in $@; do
   awk 'NR==FNR {for(i=1;i<=NF;i++) {a[i]=$i; sum[i]+=$i; c[i]++}; next}
                {for(i=1;i<=NF;i++) if(c[i] && $i>=sum[i]/c[i]) csum[i]+=$i}
        END     {printf "%s", FILENAME; 
                 for(i=1;i<=length(csum);i++) printf "%s", OFS csum[i];
                 print ""}' "$f"{,}
done;

并使用

运行
$ ./script.sh f1 f2 f3

答案 1 :(得分:0)

使用gawk的解决方案,假设awk的默认空白分隔符(6 6有两列,例如)

cat script.awk

{
    for(i=1; i<=NF; ++i){
        d[FILENAME][FNR][i] = $i
        sum[FILENAME][i] += $i
        ++rows[FILENAME][i]
    }
    if(NF>cols[FILENAME]) cols[FILENAME]=NF
    ++rows_total[FILENAME]
}
END{
    for(fname in rows_total){
        printf "%s:", fname
        for(c=1; c<=cols[fname]; ++c){
            avg = sum[fname][c] / rows[fname][c]
            sumtmp = 0
            for(r=1; r<=rows_total[fname]; ++r){
                if(d[fname][r][c] >= avg) sumtmp+=d[fname][r][c]
            }
            printf " %d", sumtmp
        }
        printf "\n"
    }
}

awk -f script.awk f1 f2 f3

你明白了,

f1: 19 20 30
f2: 11 6 2 2 3
f3: 18 16 16 7 10