Сортування декількох клавіш за допомогою сортування Unix


137

У мене є потенційно великі файли, які потрібно сортувати за 1-n клавішами. Деякі з цих клавіш можуть бути числовими, а деякі - не. Це стовпчастий файл фіксованої ширини, тому розмежувачів немає.

Чи є хороший спосіб зробити це за допомогою сорту Unix? З одним ключем це так само просто, як і використання '-n'. Я прочитав сторінку man і коротко пошукав Google, але не знайшов хорошого прикладу. Як би я міг досягти цього?

Примітка: я виключив Perl через потенціал розміру файлу. Це було б в крайньому випадку.


Один або два рядки прикладних даних були б дуже корисні для створення прикладного командного рядка. Також, чи означає "1-n" клавіші, що вам потрібно сортувати за змінною кількістю клавіш? Робити це без сценаріїв буде весело ...
Кен Ніжний

У мене є PHP обгортка навколо команди сортування, щоб увімкнути функцію 1-n.
Кріс Клоберданц

Відповіді:


69

Скористайтеся -kопцією (або --key=POS1[,POS2]). Він може з’являтися кілька разів, і кожна клавіша може мати глобальні параметри (наприклад, nдля числового сортування)


7
На сторінці впорядкування: "POS - F [.C] [OPTS], де F - номер поля, а C - позиція символу в полі; обидва - походження 1." Повну документацію див. На сторінці чоловіка.
Адам Розенфілд

49
Також дивіться відповідь Андраса, якщо ви не хочете божевільний.
ron

1
Обидва вищевказані зауваження точні та додаткові. Спасибі, панове.
Кен Ніжний

314

Але будьте обережні:

Якщо ви хочете сортувати файл головним чином за полем 3, а по друге за полем 2, вам потрібно це:

sort -k 3,3 -k 2,2 < inputfile

Не так: sort -k 3 -k 2 < inputfile який сортує файл за рядком від початку поля 3 до кінця рядка (що потенційно є унікальним).

-k, --key=POS1[,POS2]     start a key at POS1 (origin 1), end it at POS2
                          (default end of line)

8
Той, що змінює життя. Дякую.
davidtbernal

2
Ого! Тепер я повинен виправити сценарій, тому що раніше я бачив лише першу відповідь вище ... добре, що я ще не залежав від виводу сценарію ....
Wildcard

Приємно! Тепер, що робити, якщо я хочу, щоб полег 3 3 був сортований числом і зворотним чином, тоді як поле 2 буде нечисельним і нормальним (у порядку зростання)? :)
Арун

2
@Arun POS пояснюється в кінці сторінки man. Ви просто додаєте параметри замовлення до номера поля таким чином:sort -k 3,3nr -k 2,2
andras

1
Aargh. Що таке контрінтуїтивний інтерфейс: -k2має бути, -k2,2а кома в кінці -k2,повинна бути «магічним кінцем рядка чи за замовчуванням».
android.weasel

94

Варіант -k - це те, що ви хочете.

-k 1.4,1.5n -k 1.14,1.15n

Використовували б позиції символів 4-5 у першому полі (це все одне поле за фіксованою шириною) та впорядковуватиметься чисельно як перший ключ.

Другим ключем також будуть символи 14-15 в першому полі.

(редагувати)

Приклад (все, що у мене є, DOS / cygwin зручний):

dir | \cygwin\bin\sort.exe -k 1.4,1.5n -k 1.40,1.60r

для даних:

12/10/2008  01:10 PM         1,564,990 outfile.txt

Сортуйте список каталогів за номером місяця (поз. 4-5) за числом, а потім за іменем файлу (поз. 40-60) у зворотному порядку. Оскільки немає вкладок, це все поле 1 для сортування.


Це лише одне поле, якщо у вхідних даних немає пробілів. Тим не менш, ваш приклад корисний.
Джонатан Леффлер

Виправлення: якщо у вхідних даних немає / вкладки /. У виводі команди "dir" DOS немає вкладок.
Клінтон Пірс

Приклади використання параметрів (числових, зворотних) надзвичайно корисні, тому що майже неможливо дізнатися, як користуватися лише зі сторінки man, а інші відповіді не згадували про це. Я б хотів, щоб я міг +2 за це. ;)
msb

22

Ось один сортувати різні стовпці у файлі csv за порядковим числом та словником, стовпці 5 та після як порядок словника

~/test>sort -t, -k1,1n -k2,2n -k3,3d -k4,4n -k5d  sort.csv
1,10,b,22,Ga
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C

~/test>cat sort.csv
2,3,a,9,C
2,2,b,20,F
2,2,c,19,Gb,hj
2,2,c,19,Gb,hi
2,2,c,19,Ga
2,2,b,22,Ga
1,10,b,22,Ga

Зверніть увагу, -k1,1n означає числове значення, починаючи з стовпця 1 і закінчуючи на стовпці 1. Якби я зробив це нижче, він би з'єднав стовпці 1 і 2, зробивши 1,10 відсортованими як 110

~/test>sort -t, -k1,2n -k3,3 -k4,4n -k5d  sort.csv
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C
1,10,b,22,Ga

1
Це найкраща відповідь, оскільки вона показує, як використовувати різні перемикачі для різних стовпців
xaxa

12

Я вірю у вашому випадку щось подібне

sort -t@ -k1.1,1.4 -k1.5,1.7 ... <inputfile

буде працювати краще. @ є роздільником поля, переконайтеся, що це символ, який ніде не з’являється. то ваше введення вважається таким, що складається з однієї колонки.

Редагувати: мабуть, клінт вже дав подібну відповідь, вибачте. Як він вказує, прапори 'n' і 'r' можуть бути додані до кожної опції -k ....


Навіть незважаючи на те, що роздільник за замовчуванням, який відповідає документам gnu.org/software/coreutils/manual/html_node/…, є простором, іноді кількість полів - це не те, що ви очікували. Можливо, як тут говорили інші через налаштування локальної локації LC_CTYPE. Коли сумніваєтесь, рахуйте з початку рядка!
Бред Дре

5

Зауважте, що також може бути бажаним стабілізувати сортування за допомогою -sперемикача, так що однаково ранговані лінії підтримують свій вихідний відносний порядок і на виході.


2

Я просто хочу додати кілька порад, коли ви використовуєте сортування, будьте уважні до своєї локальної локації, яка впливає на порядок порівняння ключів. Я зазвичай явно використовую LC_ALL = C, щоб зробити локальний, що я хочу.


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