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


180

У мене є дані у такому форматі:

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'

Який правильний спосіб це зробити?

Ось зразкові дані .

Відповіді:


312

Використовуючи bash , це зробить трюк:

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

Помітьте знак долара перед рядком з одним котируванням. Ви можете прочитати про це у розділах цитування ANSI-C сторінки bash man .


2
Використовуйте '"'"' для використання всередині псевдоніма.
Пабло A

чи можете ви показати, як передати цей деліметр для сортування в команді awk? як в awk '{print $0 | "sort -nr" > "outfile" }' datafile, за винятком униклого деліметра табуляції, що надсилається команді сортування.
Мерлін

11

За замовчуванням роздільник поля не переходить до порожнього переходу, тому вкладка повинна працювати чудово.

Однак стовпці індексуються базовою 1 і базовою 0, так що ви, мабуть, хочете

sort -k4nr file.txt

сортувати file.txt за колонкою 4 чисельно у зворотному порядку. (Хоча дані у запитанні мають навіть 5 полів, тому останнє поле буде індексом 5.)


4
Це буде працювати лише в тому випадку, якщо кількість символів пробілу між полями, розділеними вкладками, однакове для всіх рядків введення.
Ларс Хагсет

5

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

Однак остерігайтеся, оскільки копіювання та вставлення з іншого місця зазвичай не зберігає вкладки.


Це найкраща (найбільш портативна) відповідь. emacs також дозволяє робити це в режимі "котировані вставки": C-q <tab>наприклад. Я думаю, що це також ^Vв нано.
Wyatt8740

3

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


1
Використовуйте <C-v><Tab>для того, щоб вставити вкладку, якщо клавіша вкладки використовується для автоматичного заповнення вашої оболонки.
Júda Ronén

1
Цитування ANSI $'\t'працює у ksh, zsh та bash. Оболонка Борна не підтримує її. Дивіться цей пост: unix.stackexchange.com/a/371873/201820
codeforester

1

труба через щось подібне awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'. Це змінить пробіли на вкладки.


@MB: Мені потрібно тримати простір недоторканим.
neversaint

1
Існує безперечно більш чистий спосіб зробити це, але ніщо не заважає вам пропустити його через awk, змінити пробіли на вкладки, сортувати дані, а потім проправити їх через awk знову, змінивши вкладки на пробіли.
Мічіель Буддінг

1
Це не спрацює, якщо є суміш вкладок і пробілів, які ви хочете зберегти.
Джеймс Томпсон,

1

Взагалі зберігання таких даних не є великою справою, якщо ви можете цього уникнути, оскільки люди завжди плутають вкладки та пробіли.

Вирішити свою проблему дуже просто в мовах сценаріїв, таких як 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";

1

Я хотів рішення для сортування Gnu у Windows, але жодне з перерахованих вище рішень не працювало для мене в командному рядку.

Використовуючи підказку Ллойда, для мене працював наступний пакетний файл (.bat).

Введіть символ вкладки в подвійних лапках.

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

1
Так, фокус полягає в тому, щоб помістити його у .bat файл, інакше він не працюватиме
Карлос Рендон

1

У мене виникли проблеми з сортуванням у cygwin у bash оболонці при використанні 'general-numeric-sort'. Якщо я вказав -t$'\t' -kFg, де F - номер поля, він не працював, але коли я вказав і те, -t$'\t'і -kF,Fg(наприклад, -k7,7gдля 7-го поля), він працював. -kF,Fgбез того -t$'\t'не вийшло.


0

Якщо ви хочете полегшити себе лише наявними вкладками, замініть пробіли вкладками:

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

Мій тр не читає файли, лише передає XD. usage: tr [-Ccsu] string1 string2
The Unfun Cat

1
tr string1 string2 <some-file. Все може прочитати файл, поки він може прочитати stdin.
Рандаль Шварц

0

Відповідь Ларса Хагзета працював лише в командному рядку для мене, де він видає цю помилку, якщо виконується з сценарію оболонки:

сортувати: вкладка "багато символів" $ \ t "

Рішення, якщо воно закодовано в сценарії оболонки, якщо хтось шукає

sort -t'    '

символ вкладки знаходиться між цитатою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.