Sorting a tab delimited file

LinuxUnixSortingCsv

Linux Problem Overview


I have a data with the following format:

foo<tab>1.00<space>1.33<space>2.00<tab>3

Now I tried to sort the file based on the last field decreasingly. I tried the following commands but it wasn't sorted as we expected.

$ sort -k3nr file.txt  # apparently this sort by space as delimiter

$ sort -t"\t" -k3nr file.txt
  sort: multi-character tab `\\t'

$ sort -t "`/bin/echo '\t'`" -k3,3nr file.txt
  sort: multi-character tab `\\t'

What's the right way to do it?

Here is the [sample data][1].

[1]: http://drop.io/hidden/5lmlo8s1th2eea/asset/ZmlsZS10eHQtZ3o= "Sample Data"

Linux Solutions


Solution 1 - Linux

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.

Solution 2 - Linux

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

Solution 3 - Linux

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.

Solution 4 - Linux

The $ solution didn't work for me. However, By actually putting the tab character itself in the command did: sort -t'' -k2

Solution 5 - Linux

pipe it through something like awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. This will change the spaces to tabs.

Solution 6 - Linux

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";

Solution 7 - Linux

I wanted a solution for Gnu sort on Windows, but none of the above solutions worked for me on the command line.

Using Lloyd's clue, the following batch file (.bat) worked for me.

Type the tab character within the double quotes.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

Solution 8 - Linux

I was having this problem with sort in cygwin in a bash shell when using 'general-numeric-sort'. If I specified -t$'\t' -kFg, where F is the field number, it didn't work, but when I specified both -t$'\t' and -kF,Fg (e.g -k7,7g for the 7th field) it did work. -kF,Fg without the -t$'\t' did not work.

Solution 9 - Linux

If you want to make it easier for yourself by only having tabs, replace the spaces with tabs:

tr " " "\t" < <file> | sort <options>

Solution 10 - Linux

Lars Haugseth answer only worked from the command line for me where it gives this error if executed from a shell script:

sort: multi-character tab ‘$\t’

The solution if it's coded in a shell script if anyone's looking is

sort -t'    '

the tab character is in between the quote.

Solution 11 - Linux

sort -t "$(printf '\t')" works for me

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionneversaintView Question on Stackoverflow
Solution 1 - LinuxLars HaugsethView Answer on Stackoverflow
Solution 2 - LinuxlaaltoView Answer on Stackoverflow
Solution 3 - LinuxBrian CarlsenView Answer on Stackoverflow
Solution 4 - LinuxLloydView Answer on Stackoverflow
Solution 5 - LinuxMichiel BuddinghView Answer on Stackoverflow
Solution 6 - LinuxJames ThompsonView Answer on Stackoverflow
Solution 7 - LinuxLawrence NoronhaView Answer on Stackoverflow
Solution 8 - LinuxDannyView Answer on Stackoverflow
Solution 9 - LinuxThe Unfun CatView Answer on Stackoverflow
Solution 10 - LinuxmightyandweakcoderView Answer on Stackoverflow
Solution 11 - LinuxJasonView Answer on Stackoverflow