# How can I sort a mix of numeric and alphabetic characters?

How can I sort input such as this using the `sort`

command? I would like the numbers to be sorted numerically before the letters.

```
10
11
12
1
13
14
15
16
17
18
19
20
21
2
22
3
4
5
6
7
8
9
X
Y
```

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).

you can use

```
cat number.txt|sort -n
```

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})
```