Awk: find minimum and maximum columns

I use awk to work with a simple .dat file that contains several rows of data, and each row has 4 columns separated by a single space. I want to find the minimum and maximum of the first column.

The data file is as follows:

9 30 8.58939 167.759
9 38 1.3709 164.318
10 30 6.69505 169.529
10 31 7.05698 169.425
11 30 6.03872 169.095
11 31 5.5398 167.902
12 30 3.66257 168.689
12 31 9.6747 167.049
4 30 10.7602 169.611
4 31 8.25869 169.637
5 30 7.08504 170.212
5 31 11.5508 168.409
6 31 5.57599 168.903
6 32 6.37579 168.283
7 30 11.8416 168.538
7 31 -2.70843 167.116
8 30 47.1137 126.085
8 31 4.73017 169.496

The commands I used are as follows.

min=`awk 'BEGIN{a=1000}{if ($1<a) a=$1 fi} END{print a}' mydata.dat`
max=`awk 'BEGIN{a=   0}{if ($1>a) a=$1 fi} END{print a}' mydata.dat`

However, the output is min = 10 and max = 9 .

(Similar commands can return me the correct minimum and maximum of the second column.)

Can someone tell me where I was wrong? Thank!

+4
source share
3 answers

Awk guesses about the type.

"10" "4", "1" "4". , :

min=`awk 'BEGIN{a=1000}{if ($1<0+a) a=$1} END{print a}' mydata.dat`
max=`awk 'BEGIN{a=   0}{if ($1>0+a) a=$1} END{print a}' mydata.dat`
+6

, script :

if ($1<a) a=$1 fi

final fi awk, , a=$1 fi , TELLING awk, a , , , $1<a.

, - max/min, , . script:

$ cat tst.awk
BEGIN { min = max = "NaN" }
{
    min = (NR==1 || $1<min ? $1 : min)
    max = (NR==1 || $1>max ? $1 : max)
}
END { print min, max }

$ awk -f tst.awk file
4 12

$ awk -f tst.awk /dev/null
NaN NaN

$ a=( $( awk -f tst.awk file ) )
$ echo "${a[0]}"
4
$ echo "${a[1]}"
12

NaN , , .

+3

non-awk answer:

cut -d" " -f1 file |
sort -n |
tee >(echo "min=$(head -1)") \
  > >(echo "max=$(tail -1)")

This tee command is perhaps a little too smart. tee duplicates the stdin stream into file names as arguments, and also passes the same data to stdout. I use process substitution to filter threads.

The same effect can be used (with a lower coloring) to extract the first and last lines of the data stream:

cut -d" " -f1 file | sort -n | sed -n '1s/^/min=/p; $s/^/max=/p'

or

cut -d" " -f1 file | sort -n | { 
    read line
    echo "min=$line"
    while read line; do max=$line; done
    echo "max=$max"
}
+2
source

Source: https://habr.com/ru/post/1583875/


All Articles