2
NODE_154_length  847 2997
NODE_154_length 3283    4509
NODE_154_length 4672    5715
NODE_154_length 6977    7768
NODE_29_length  3790    4317
NODE_29_length  4356    4712
NODE_29_length  4356    4712
NODE_29_length  158 319
NODE_29_length  1   97
NODE_29_length  1   96

I want the output like:

NODE_154_length  847 2997
NODE_154_length 3283    4509
NODE_154_length 4672    5715
NODE_154_length 6977    7768
NODE_29_length  1   97
NODE_29_length  1   96
NODE_29_length  158 319
NODE_29_length  4356    4712
NODE_29_length  4356    4712
NODE_29_length  3790    4317

OR

NODE_29_length   1   97
NODE_29_length  1   96
NODE_29_length  158 319
NODE_154_length 847 2997
NODE_154_length 3283    4509
NODE_29_length  3790    4317
NODE_29_length  4356    4712
NODE_29_length  4356    4712
NODE_154_length 4672    5715
NODE_154_length 6977    7768

sort -k2,2 file This sorts all column 2 and gives:

NODE_100_length_46867_cov_66.420166  1   50
NODE_104_length_141_cov_120.127663  1   210
NODE_104_length_141_cov_120.127663  1   210
NODE_104_length_141_cov_120.127663  1   225

This disturbs the complete coordinates for each node.

If I try sort -k2 file This again gives me weird output, not in sorted manner.

I am not able to understand how to use -k option in Linux. I am using bash, Linux 13.10

2
  • 2
    sort -k1,1 -k2,2n or sort -s -k2,2n Commented Feb 14, 2014 at 19:31
  • @StephaneChazelas Thank you for your reply. That works perfectly. Can you please explain me, how that flags are working? Commented Feb 14, 2014 at 19:39

1 Answer 1

6

The syntax is -k<start>[<flags>][,<end>[<flags>]] (if ,<end> is omitted, that's the end of the line).

That defines the part of the line to sort on as one sort key.

<start> and <end> refer to field numbers. 2 for <start> means the beginning of the 2nd field, while 2 for <end> means the end of the 2nd field.

By default, fields are delimited by the transition between a non-blank and a blank. For instance, in:

NODE_154_length  847 2997

The fields are:

[NODE_154_length][  847][ 2997]

Doing sort -k2, sorts on the part of the line that starts at the beginning of the 2nd field and ends at the end of the line. So above, on [  847 2997]. sort is doing lexical comparisons be default.

sort -k2,2 would consider only [  847] for comparison.

If you want to do numerical comparison on a particular key, you have to add the n <flag> to the sort key. That way,   847 would be converted to a number. That's why -k2,2n and -k2n would work the same because both the [  847] and [  847 2997] strings convert to number 847.

So, to get your first result, you want to sort on the first field lexicographically, and then (where the first fields sort equally) on the second field numerically. That's written:

sort -k1,1 -k2,2n

In the second case, you want to sort on the second field numerically and when they sort the same, preserve the original order.

That's where you need the -s option for stable sort:

sort -s -k2,2n

(by default, where the keys sort the same, sort resorts to doing a lexical comparison of the whole line; -s disables that).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .