Question

I have a file with an variable number of columns:

Input:

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

I want to print the max and min of each column:

Desired output:

max:    7 2 5
min:    1 0 -1

For a single column, e.g. $1, I know I can find the max and min using something like:

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

Question

How can I extend this to loop over all columns (not necessarily just the 3 in my example)?

Many thanks!

Was it helpful?

Solution

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

output:

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

OTHER TIPS

Like this

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

Let's try to make it a bit shorter by using the min=(current<min?current:min) expression. This is a ternary operator that is the same as saying if (current<min) min=current.

Also, printf "%.2g%s", min[i], (i==NF?"\n":" ") prints the new line on the END{} block whenever it reaches the last field.

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

Sample output:

$ 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top