我在作为参数给出的文件中有一些矩阵。我需要找到每列的平均值,并且只列出列中大于或等于列平均值的数字。
例如:
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
我知道我遇到了所有阵列问题。
答案 0 :(得分:1)
此处bash
和awk
的组合将简化脚本
将其另存为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