How to rank numbers in array by Unix?

If that list was in a file, one per line, I'd do something like:

sort -nu file |
  awk 'NR == FNR {rank[$0] = NR; next}
      {print rank[$0]}' - file

If it was in a zsh $array:

sorted=(${(nou)array})
for i ($array) echo $sorted[(i)$i]

That's the same principle as for the awk version above, the rank is the index NR/(i) in the numerically (-n/(n)) ordered (sort/(o)), uniqued (-u/(u)) list of elements.

For your average rank:

sort -n file |
  awk 'NR == FNR {rank[$0] += NR; n[$0]++; next}
  {print rank[$0] / n[$0]}' - file

Which gives:

5
7
1
6
2.5
2.5
4

(use sort -rn to reverse the order like in your Google Spreadsheet version).


nl x | sort  -k 2n | nl | sort -k 2n | cut -f1

... it has a slightly different behavior in case of duplicates:

 nl x | sort  -k 2n | nl | sort -k 2n | cut -f1,3
 5  17 
 7  94 
 1  3 
 6  52 
 2  4 
 3  4 
 4  9

With just GNU awk:

awk '
    FNR == NR {numbers[$1]=1; next} 
    FNR == 1 {
        n = asorti(numbers, sorted, "@ind_num_asc")
        for (i=1; i<=n; i++) rank[sorted[i]] = i
    }
    {print rank[$1]}
' file file