Сортировка файла с разделителями табуляции

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

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'

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

здесь пример данных.

9 ответов


С помощью Баш, это сделает трюк:

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

обратите внимание на знак доллара перед строкой с одной кавычкой. Вы можете прочитать о его в ANSI-C цитирование разделов Баш man page.


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

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

sort -k4nr file.txt

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


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

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


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


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


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

решение вашей проблемы очень просто на языке сценариев, таком как 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";

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

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

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

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

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


Если вы хотите сделать это проще для себя, только имея вкладки, замените пробелы вкладками:

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