Baldrick
Baldrick

Reputation: 11012

Bash/Linux Sort by 3rd column using custom field seperator

I can't seem to sort the following data as I would like;

find output/ -type f -name *.raw | sort 
output/rtp.0.0.raw
output/rtp.0.10.raw
output/rtp.0.11.raw
output/rtp.0.12.raw
output/rtp.0.13.raw
output/rtp.0.14.raw
output/rtp.0.15.raw
output/rtp.0.16.raw
output/rtp.0.17.raw
output/rtp.0.18.raw
output/rtp.0.19.raw
output/rtp.0.1.raw
output/rtp.0.20.raw
output/rtp.0.2.raw
output/rtp.0.3.raw
output/rtp.0.4.raw
output/rtp.0.5.raw
output/rtp.0.6.raw
output/rtp.0.7.raw
output/rtp.0.8.raw
output/rtp.0.9.raw

In the above example I haven't passed any arguments to the sort command. No matter what options I used I can't get closer to my desired results. I would like the following output;

find output/ -type f -name *.raw | sort 
output/rtp.0.0.raw
output/rtp.0.1.raw
output/rtp.0.2.raw
output/rtp.0.3.raw
output/rtp.0.4.raw
output/rtp.0.5.raw
output/rtp.0.6.raw
output/rtp.0.7.raw
output/rtp.0.8.raw
output/rtp.0.9.raw
output/rtp.0.10.raw
output/rtp.0.11.raw
output/rtp.0.12.raw
output/rtp.0.13.raw
output/rtp.0.14.raw
output/rtp.0.15.raw
output/rtp.0.16.raw
output/rtp.0.17.raw
output/rtp.0.18.raw
output/rtp.0.19.raw
output/rtp.0.20.raw

I have tried with -t . option to set a field separator to the full stop. Also I have experimented with the -k option to specify the field, and -g, -h, -n, but none of the options are helping. I can't see anything else in the man pages that would do as I require, unless I haven't understood the man pages correctly and overlooked my answer.

Can I produce the results I require with sort, and if so, how?

Additionally, it's vary rare but sometimes the 2nd column which shows as '0' all the way down may increment. Can that be factored into the sort?

Upvotes: 0

Views: 5961

Answers (3)

Simon
Simon

Reputation: 11

sort -t'.' -n -k3

to sort the 3th column from smallest to biggest

And if you want to sort from biggest to smallest, you can use '-r' option :

sort -t'.' -n -r -k3

Upvotes: 1

William Pursell
William Pursell

Reputation: 212248

Fedorqui's solution is good (+1), but not all versions of sort support -V. For those versions that do not, you need to do a little more work than fedorqui's original solution. This should suffice:

sort -t. -k2,2 -k3,3 -n

You get a slightly different sort (eg, '05' sorts before '1' instead of after) if you use:

sort -t. -k2g

(Note that -g is also non-standard, and not available in all versions of sort).

Upvotes: 4

fedorqui
fedorqui

Reputation: 289755

This makes it:

$ sort -t'.' -n -k3 a
output/rtp.0.0.raw
output/rtp.0.1.raw
output/rtp.0.2.raw
output/rtp.0.3.raw
output/rtp.0.4.raw
output/rtp.0.5.raw
output/rtp.0.6.raw
output/rtp.0.7.raw
output/rtp.0.8.raw
output/rtp.0.9.raw
output/rtp.0.10.raw
output/rtp.0.11.raw
output/rtp.0.12.raw
output/rtp.0.13.raw
output/rtp.0.14.raw
output/rtp.0.15.raw
output/rtp.0.16.raw
output/rtp.0.17.raw
output/rtp.0.18.raw
output/rtp.0.19.raw
output/rtp.0.20.raw

As you see we need different options:

  • -t'.' to set the dot . as the field separator.
  • -n to make it numeric sort.
  • -k3 to check the 3rd column.

Update

This also makes it:

$ sort -t'.' -V -k2 a
output/rtp.0.0.raw
output/rtp.0.1.raw
output/rtp.0.2.raw
output/rtp.0.3.raw
output/rtp.0.4.raw
output/rtp.0.5.raw
output/rtp.0.6.raw
output/rtp.0.7.raw
output/rtp.0.8.raw
output/rtp.0.9.raw
output/rtp.0.10.raw
output/rtp.0.11.raw
output/rtp.0.12.raw
output/rtp.0.13.raw
output/rtp.0.14.raw
output/rtp.0.15.raw
output/rtp.0.16.raw
output/rtp.0.17.raw
output/rtp.0.18.raw
output/rtp.0.19.raw
output/rtp.0.20.raw

As you see we need different options:

  • -t'.' to set the dot . as the field separator.
  • -V to make it sort based on version.
  • -k2 to check the 2nd column.

Upvotes: 7

Related Questions