我有一个文件,其中包含矩阵形式的数值。我编写了一个 awk 脚本,该脚本打印标题,然后如果列中的值小于 5 且大于 0,则将 1 添加到列“总和”中。然后,最后打印每列的总和。这部分工作正常:
awk '
BEGIN {FS=OFS=" "}
NR==1 {print}
NR>1 {for (i=1;i<=NF;i++) if ($i < 5 && $i > 0) a[i]+=1}
END {for (i=1;i<=NF;i++) printf $a[i]
}' snp_fake2.txt > tmp.txt`
我的目标是,如果该列的总和大于某个值 THRESHOLD,则打印整个列。我尝试在第二个 for 循环后添加一个 if 语句来确定列总和 a[i] 是否 > THRESHOLD,然后打印该列:
awk '
BEGIN {FS=OFS=" "}
NR==1 {print}
NR>1 {for (i=1;i<=NF;i++) if ($i < 5 && $i > 0) a[i]+=1}
END {for (i=1;i<=NF;i++) if (a[i] < THRESHOLD) printf $i
}' snp_fake2.txt > tmp.txt`
但是当我运行这个脚本时,它不会输出整个列,而只会输出一个数字。我怎样才能打印整个列而不是仅仅打印单个值?
答案1
AWK 每次处理文件中的一行。它不记忆前几行。END 规则在处理完最后一行后执行。此时 AWK 无法打印列 $i 中的所有条目,因为它只知道列 $i 的一个值:最后一行的值。
您的目标需要对文件进行两次传递:一次计算列总和,第二次打印出整个列(针对相应的列)。为此,您可以编写一个 shell 脚本,调用 awk 来计算总和,然后调用 awk(或其他程序)来打印列。
答案2
如果我理解正确的话,一种方法是使用二维数组。它适用于 GNU awk。
echo -e '1 4 7\n2 5 8\n3 6 9' | awk '
{ for (i=1;i<=NF;i++) {
field[i][NR]=$i
if ($i < 5 && $i > 0) {
a[i]+=1
}
}
}
END {
for (i in a) {
if (a[i] > 2) {
for (j in field[i]) print field[i][j]
}
}
}'