300

I have a file of 2 columns and n number of rows.

column1 contains names and column2 age.

I want to sort the content of this file in ascending order based on the age (in second column).

The result should display the name of the youngest person along with name and then second youngest person and so on...

Any suggestions for a one liner shell or bash script.

Tms91
  • 3,456
  • 6
  • 40
  • 74
Angelo
  • 4,829
  • 7
  • 35
  • 56

5 Answers5

450

You can use the key option of the sort command, which takes a "field number", so if you wanted the second column:

sort -k2 -n yourfile

-n, --numeric-sort compare according to string numerical value

For example:

$ cat ages.txt 
Bob 12
Jane 48
Mark 3
Tashi 54

$ sort -k2 -n ages.txt 
Mark 3
Bob 12
Jane 48
Tashi 54
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Matt Ryall
  • 9,977
  • 5
  • 24
  • 20
  • 1
    also note that using `-h` instead of `-n` will sort human readable values like `2G` or `3K` as well as numbers separated with commas e.g. `1,234.5` – chillitom Aug 29 '18 at 10:58
  • Faced issue with "wrong" ordering. Pay attention to man "*** WARNING *** The locale specified by the environment affects sort order. Set `LC_ALL=C` to get the traditional sort order that uses native byte values." (for string match case without `-n`) – x'ES Sep 29 '18 at 00:28
  • This doesn't consider spaces in the first column neither works if there are more columns after the second, since -k read until the line end. Supposing it is a TSV file a better solution is ```sort -t$'\t' -k2 -n FILE``` – tuxErrante Apr 20 '19 at 16:28
  • 2
    you might need to specify your delimiter using the -t option – spectrum Sep 19 '19 at 00:49
112

Solution:

sort -k 2 -n filename

more verbosely written as:

sort --key 2 --numeric-sort filename


Example:

$ cat filename
A 12
B 48
C 3

$ sort --key 2 --numeric-sort filename 
C 3
A 12
B 48

Explanation:

  • -k # - this argument specifies the first column that will be used to sort. (note that column here is defined as a whitespace delimited field; the argument -k5 will sort starting with the fifth field in each line, not the fifth character in each line)

  • -n - this option specifies a "numeric sort" meaning that column should be interpreted as a row of numbers, instead of text.


More:

Other common options include:

  • -r - this option reverses the sorting order. It can also be written as --reverse.
  • -i - This option ignores non-printable characters. It can also be written as --ignore-nonprinting.
  • -b - This option ignores leading blank spaces, which is handy as white spaces are used to determine the number of rows. It can also be written as --ignore-leading-blanks.
  • -f - This option ignores letter case. "A"=="a". It can also be written as --ignore-case.
  • -t [new separator] - This option makes the preprocessing use a operator other than space. It can also be written as --field-separator.

There are other options, but these are the most common and helpful ones, that I use often.

Stephan
  • 41,764
  • 65
  • 238
  • 329
DCurro
  • 1,797
  • 1
  • 15
  • 16
  • @Angelo This answer was presumably posted years after you've accepted an answer for this question, but have you considered it as the new accepted answer? – Jonathan Y. Jul 14 '17 at 11:44
  • 1
    Option `-t` was real life saver!! when your columns have spaces and columns differ by a given character like `,` or a tab – AKS Feb 25 '20 at 21:12
22

For tab separated values the code below can be used

sort -t$'\t' -k2 -n

-r can be used for getting data in descending order.
-n for numerical sort
-k, --key=POS1[,POS2] where k is column in file
For descending order below is the code

sort -t$'\t' -k2 -rn
Saurabh
  • 7,525
  • 4
  • 45
  • 46
8

Use sort.

sort ... -k 2,2 ...
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 9
    You also need to use -n to sort based on ages (numeric sort). Otherwise '11' will come before '2'. – Matt Ryall Jun 22 '11 at 11:24
  • @MattRyall i have similar requirement but my second column has alphabet its like users. and first column has some blank cells. i am able to sort the users properly but i wanted the blank cell should come at the end. this is how i do. Please help me if know the trick (head -n 1 Users.csv && tail -n +2 Users.csv | sort -t ',' -k 2) > UsersNew.csv – Prashant Naik Sep 12 '22 at 11:34
0

Simply

$ sort -k2,2n <<<"$data"
Logan Lee
  • 807
  • 9
  • 21