Sort numbers

Hello,

okey so my script is using 4 variables that are either empty or numbers in the following format:

NUMBER_1 NUMBER_2 NUMBER_3 NUMBER_4

So they're basically separated by a space and I need to echo the lowest number, so far I've been doing it like this:

echo "2 3 1 3" | tr " " "\n" | sort -n | head -n1

However the problem is that I need the number 0 as well empty fields excluded.

So with my method the following examples would fail:

echo "2 3 1 0" | tr " " "\n" | sort -n | head -n1
echo "2 3  1" | tr " " "\n" | sort -n | head -n1
echo "2 3 1 3" | tr " " "\n" | sort -n | head -n1
echo " 3 1 3" | tr " " "\n" | sort -n | head -n1
echo "2 3 1 " | tr " " "\n" | sort -n | head -n1
etc.

I'm sure that one of you guys has a good solution, big thanks in advance!

% echo '2 3 42  0  10' | 
  perl -le'
    print+(sort{$a<=>$b}grep$_>0,split/ /,<>)[0]
'                               
2

Here's a brute force way:

echo " 2 3  3    1 0 " | sed "s/ $//g" | sed "s/^ //g" | tr -s '  ' ' ' | tr " " "\n" | sort -un | egrep -v "0" | head -1
1

Shorter:

echo " 2 3  3    1 0 " | tr " " "\n" | egrep -v "^ *$|0" | sort -un | head -1
1

Would be nice if someone had a non perl solution. Just bash/sad/awk/sort etc.

Edit:

Thanks purdym :slight_smile:

echo "0 2 3 5 0 8 1" | awk '{for(i=0;++i<=NF;){x=((!x && $i>0)?$i:($i>0 && $i<x)?$i:x)}}END{print x}'

Any tool with associative arrays implicitly can sort internally, like ksh93. But you just want the max:

Inline code:
 
zmax=
 
for n in 9 2 3 8 7
do
  if [ "$zmax" = "" ]
  then
    zmax=$n
    continue
  fi
 
  if (( $n > $zmax ))
  then
    zmax=$n
  fi
done
 
echo $zmax
 
 
or as a function;
 
 
max(){
  zmax=$1
  shift
 
  while [ $# != 0 ]
  do
    if (( $1 > $zmax ))
    then
      zmax=$1
    fi
    shift
  done
 
  echo $zmax
}

Thanks buddy I'm going to use your way, seems to be most effective.

You guys are great help :slight_smile: