Unix Sort with Tab Delimiter

У меня есть данные со следующим форматом:

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

Теперь я попытался отсортировать файл на основе последнего поля. Я пробовал следующие команды, но он не был отсортирован так, как мы ожидали.

$ 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'

Какой правильный способ сделать это?

Вот примеры данных.

Ответ 1

Используя bash, это сделает трюк:

$ sort -t$'\t' -k3 -nr file.txt

Обратите внимание на знак доллара перед строкой с одним кавычком. Вы можете прочитать о это в разделе ANSI-C Quoting страницы bash.

Ответ 2

По умолчанию разделитель полей не является пустым для пустого перехода, поэтому вкладка должна работать нормально.

Однако столбцы индексируются base 1 и base 0, поэтому вы, вероятно, захотите

sort -k4nr file.txt

сортировать file.txt по столбцу 4 численно в обратном порядке. (Хотя данные в вопросе имеют даже 5 полей, поэтому последним полем будет индекс 5.)

Ответ 3

Вам нужно поместить фактический символ табуляции после -t\и сделать это в оболочке, на которую вы нажмете ctrl-v, а затем на символ табуляции. Большинство оболочек, которые я использовал, поддерживают этот режим записи в виде буквальной вкладки.

Остерегайтесь, однако, поскольку копирование и вставка из другого места обычно не сохраняет вкладки.

Ответ 4

проведите его через что-то вроде awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. Это изменит пробелы на вкладки.

Ответ 5

В целом данные, подобные этому, не очень полезны, если вы можете избежать этого, потому что люди всегда путают вкладки и пробелы.

Решение вашей проблемы очень просто на языке сценариев, например Perl, Python или Ruby. Вот пример кода:

#!/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";

Ответ 6

Решение $не работало для меня. Тем не менее, фактически положив сам символ табуляции в команду: sort -t '' -k2

Ответ 7

Мне нужно решение для сортировки Gnu в Windows, но ни один из вышеперечисленных решений не работал у меня в командной строке.

Используя ключ Lloyd, для меня работал следующий командный файл (.bat).

Введите символ табуляции в двойные кавычки.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

Ответ 8

У меня возникла проблема с сортировкой в ​​cygwin в оболочке bash при использовании 'general-numeric-sort'. Если я указал -t$'\t' -kFg, где F - номер поля, это не сработало, но когда я указал как -t$'\t', так и -kF,Fg (например, -k7,7g для 7-го поля), это сработало. -kF,Fg без -t$'\t' не работает.