How can I sort numbers in a unix shell?

As @terdon noticed, the inclusion of X and Y and the fact that the numbers run from 1 to 22 identifies this as a possible list of human chromosomes (which is why he says that chromosome M (mitochondrial) may be missing).

To sort a list of numbers, one would usually use sort -n:

$ sort -n -o list.sorted list

where list is the unsorted list, and list.sorted will be the resulting sorted list.

With -n, sort will perform a numerical sort on its input. However, since some of the input is not numerical, the result is probably not the intended; X and Y will appear first in the sorted list, not last (the sex chromosomes are usually listed after chromosome 22).

However, if you use sort -V (for "version sorting"), you will actually get what you want:

$ sort -V -o list.sorted list
$ cat list.sorted
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
X
Y

This will probably still not work if you do add M as that would be sorted before X and not at the end (which I believe is how it's usually presented).


If you mean they should sort in the 1..22, X, Y, M order, then you can translate those X, Y, M to numbers before sorting and back after sorting:

sed 's/X/23/;s/Y/24/;s/M/25/' < file | sort -n | sed 's/23/X/;s/24/Y/;s/25/M/'

If those numbers are in a zsh array, you can apply an arbitrary sort order using this hack:

k=({1..22} X Y M) v=({01..25})
typeset -A rank=(${k:^v})

unsorted=(22 Y 5 X M 13)
sorted=(/(e'{reply=($unsorted)}'oe'{REPLY=$rank[$REPLY]}'))

Or if the members of $unsorted are unique, use array intersection:

all=({1..22} X Y M)
unsorted=(22 Y 5 X M 13)
sorted=(${all:*unsorted})

Tags:

Sort