我有一个列数可变的文件:
输入:
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)?
非常感谢!
答案 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