Sorting by Columns It is possible to sort files/streams on a single column, multiple columns, or ranges of columns. To do this use the -k option to indicate these columns. The default delimiter used to identify columns is white space (blank characters). If you need to use a different column delimiter use the -t option.
To sort by a delimiter pass the -t option to sort along with the delimiter value. For a CSV file this would be , . This can be combined with the -k option to sort on fields within a CSV. The result will be written to standard output.
Using bash, this will do the trick:
$ sort -t$'\t' -k3 -nr file.txt
Notice the dollar sign in front of the single-quoted string. You can read about it in the ANSI-C Quoting sections of the bash man page.
By default the field delimiter is non-blank to blank transition so tab should work just fine.
However, the columns are indexed base 1 and base 0 so you probably want
sort -k4nr file.txt
to sort file.txt by column 4 numerically in reverse order. (Though the data in the question has even 5 fields so the last field would be index 5.)
You need to put an actual tab character after the -t\ and to do that in a shell you hit ctrl-v and then the tab character. Most shells I've used support this mode of literal tab entry.
Beware, though, because copying and pasting from another place generally does not preserve tabs.
The $ solution didn't work for me. However, By actually putting the tab character itself in the command did: sort -t'' -k2
pipe it through something like awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'
. This will change the spaces to tabs.
In general keeping data like this is not a great thing to do if you can avoid it, because people are always confusing tabs and spaces.
Solving your problem is very straightforward in a scripting language like Perl, Python or Ruby. Here's some example code:
#!/usr/bin/perl -w
use strict;
my $sort_field = 2;
my $split_regex = qr{\s+};
my @data;
push @data, "7 8\t 9";
push @data, "4 5\t 6";
push @data, "1 2\t 3";
my @sorted_data =
map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { [ ( split $split_regex, $_ )[$sort_field], $_ ] }
@data;
print "unsorted\n";
print join "\n", @data, "\n";
print "sorted by $sort_field, lines split by $split_regex\n";
print join "\n", @sorted_data, "\n";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With