Dire
Dire

Reputation: 35

How to use awk to find the largest and smallest numbers?

I was trying to find the largest and the smallest numbers in one column. The output should have the the largest and the smallest number along with the names of the max and min numbers.

The awk code I wrote is this:

 BEGIN{first=1;}
     {if (first) { max = min = $2; first = 0; next;}
     if (max < $2) max=$2 cmax=$1 ; if (min > $2) min=$2 cmin=$1; }
END { print cmin min \n cmax max }

Could you help me to point out what's the problem of this code?

Upvotes: 0

Views: 1153

Answers (1)

Chris Seymour
Chris Seymour

Reputation: 85913

The problem is the lines if (max < $2) max=$2 cmax=$1 and if (min > $2) min=$2 cmin=$1 the should be if (max < $2){ max=$2; cmax=$1 } and if (min > $2){ min=$2; cmin=$1} respectively. Another error is with the line print cmin min \n cmax max which should at least be print cmin min "\n" cmax max. Errors are easierly spotted when you format the code better:

BEGIN{
    first=1
}
{
    if (first) {  # We should move this to it's own block and test against NR
        max = min = $2
        first = 0
        next
    }    
    if (max < $2) {  # confusing using max to store min
        max=$2 
        cmax=$1 
    }
    if (min > $2) { # and min to store max your operators are the wrong way round
       min=$2 
       cmin=$1
    } 
}
END { 
    print cmin min "\n" cmax max  
}

Your script should now work but still has a few issue, compare with the version below:

NR==1{                   # If we are on the first line in the file
    min=max=$2           # Set initial min/max values
    next                 # Skip to next line
}
{
    if ($2 > max) {      # If the value in field 2 is greater than current max
        max=$2           # Store the new values
        cmax=$1 
    } 
    if ($2 < min) {      # If the value in field 2 is less than current min
        min=$2           # Store the new values
        cmin=$1
    } 
}
END {
    # Use printf to properly format the output
    printf "%s %d\n%s %d\n",cmin,min,cmax,max
}

A side note: if you presort the file on the second field you can be more concise:

sort -nk2 file | awk 'NR==1{print}END{print}' 

Upvotes: 2

Related Questions