在awk中查找每列的最大/最小值

时间:2014-05-07 08:46:59

标签: awk

我有一个列数可变的文件:

输入

1 1 2
2 1 5
5 2 3
7 0 -1
4 1 4

我想打印每列的最大值和最小值:

期望的输出

max:    7 2 5
min:    1 0 -1

对于单个列,例如$ 1,我知道我可以使用类似的东西找到最大值和最小值:

awk '{if(min==""){min=max=$1}; if($1>max) {max=$1}; if($1<min) {min=$1};} END {printf "%.2g %.2g\n", min, max}' 

问题

如何将其扩展为遍历所有列(不一定只是我示例中的3)?

非常感谢!

3 个答案:

答案 0 :(得分:2)

awk 'NR==1{for(i=1;i<=NF;i++)min[i]=max[i]=$i;}
{for(i=1;i<=NF;i++){if($i<min[i]){min[i]=$i}else if($i>max[i])max[i]=$i;}}
END{printf "max:\t"; for(i in max) printf "%d ",max[i]; printf "\nmin:\t"; for(i in min)printf "%d ",min[i];}' input.txt

input.txt中:

1 1 2 2
2 1 5 3
5 2 3 10
7 0 -1 0
4 1 4 5

输出:

max:    7 2 5 10 
min:    1 0 -1 0 

答案 1 :(得分:2)

喜欢这个

awk 'NR==1{for(i=1;i<=NF;i++){xmin[i]=$i;xmax[i]=$i}}
     {for(i=1;i<=NF;i++){if($i<xmin[i])xmin[i]=$i;if($i>xmax[i])xmax[i]=$i}}
     END{for(i=1;i<=NF;i++)print xmin[i],xmax[i]}' file

答案 2 :(得分:1)

让我们尝试使用min=(current<min?current:min)表达式缩短它。这是一个三元运算符,与if (current<min) min=current一样。

此外,printf "%.2g%s", min[i], (i==NF?"\n":" ")只要到达最后一个字段,就会在END{}块上打印新行。

awk 'NR==1{for (i=1; i<=NF; i++) {min[i]=$i}; next}
     {for (i=1; i<=NF; i++) { min[i]=(min[i]>$i?$i:min[i]); max[i]=(max[i]<$i?$i:max[i]) }}
     END {printf "min: "; for (i=1;i<=NF;i++) printf "%.2g%s", min[i], (i==NF?"\n":" "); 
          printf "max: "; for (i=1;i<=NF;i++) printf "%.2g%s", max[i], (i==NF?"\n":" ")}' file

示例输出:

$ awk 'NR==1{for (i=1; i<=NF; i++) {min[i]=$i}; next} {for (i=1; i<=NF; i++) { min[i]=(min[i]>$i?$i:min[i]); max[i]=(max[i]<$i?$i:max[i]) }} END {printf "min: "; for (i=1;i<=NF;i++) printf "%.2g%s", min[i], (i==NF?"\n":" "); printf "max: "; for (i=1;i<=NF;i++) printf "%.2g%s", max[i], (i==NF?"\n":" ")}' file
min: 1 0 -1
max: 7 2 5