Відсортуйте файл CSV за пріоритетом стовпця за допомогою команди “сортувати”


94

У мене є файл CSV, і я хотів би відсортувати його за пріоритетом стовпця, наприклад "упорядкувати за". Наприклад:

3;1;2
1;3;2
1;2;3
2;3;1
2;1;3
3;2;1

Якби ця ситуація була результатом "вибору", "порядок за" мав би бути таким: порядок за стовпцем2, стовпець1, стовпець3 - результат буде:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1

Я хотів би знати, як отримати той самий результат за допомогою команди "сортувати" в Unix.


4
До речі, це файл ssv (значення, розділені крапкою з комою): P
— Джон Строуд,

Відповіді:


157
sort --field-separator=';' --key=2,1,3

9
Якщо значення є числовими, ви, ймовірно, хочете розглянути можливість використання -nопції, яка буде "порівнювати за числовим значенням рядка", або -gопції, яка буде "порівнювати за загальним числовим значенням". Порівняння рядків числових значень дозволить отримати впорядковані числа, як 1,10,2,20. Принаймні це варіанти, доступні в моїй версії сортування на CentOS. Вам слід перевірити на сторінці довідки, які правильні параметри вказані у вашій версії сортування.
— Адам Порад

5
Я розуміюsort: stray character in field spec: invalid field specification ‘2,1,3’
— Мартін Тома

3
Однак sort --field-separator=',' -r -k3 -k1 -k2 source.csv > target.csvпрацював у мене.
— Мартін Тома

6
@MartinThoma минуло багато часу, але я зіткнувся з вашою проблемою і виявив це sort --field-separator=';' --key={2,1,3}. Це працювало GNU coreutils 8.4з квітня 2016 р.
— мрболічі

3
@mrbolichi позначення --key={2,1,3}використовує фігурне розширення bash
— kvantour

28

Припустимо, 3;10;3у вашому unsorted.csvфайлі є ще один рядок . Тоді я думаю, ви очікуєте числово відсортований результат:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1
3;10;3

а не в алфавітному порядку:

2;1;3
3;1;2
3;10;3
1;2;3
3;2;1
1;3;2
2;3;1

Щоб отримати це, вам потрібно використовувати -n:

sort --field-separator=';' -n -k 2,2 -k 1,1 -k 3,3 unsorted.csv

Варто згадати, що 2,2доводиться використовувати. Якщо 2використовується лише , то sortбере рядок від початку поля 2 до кінця. 2,2переконує, що використовується лише поле 2.


7
Покажчик щодо різниці між -k 2 та -k 2,2 є значним! Я пропустив це під час свого першого читання сторінки довідок. Дякую.
— usonianhorizon

Я додав кілька додаткових рядків, 3;10;3, 3:10:5, 3:10;2, 3;10;3в тому порядку , в вихідному файлі, а при використанні тільки -k 2,2 виявляється для сортування по колонці 2 і 3. Сторінка людина говорить "The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal.". У моєму випадку попередній ключ (значення = 10) справді порівнював, однак я не вказував -kкілька разів. Я не впевнений, що це надійна поведінка чи пов’язана з моєю системою (mac). Зрештою, це не має значення, якщо первинне сортування є правильним.
— Давос,

О, я бачу, є також -sстабільне сортування, яке ігнорує рівні клавіші, що, мабуть, швидше, на думку людини.
— Давос,

24

Відповідь Чарлі вище не спрацювала для мене на Cygwin (сортувати версію 2.0, текстиль GNU), зробили такі:

sort -t"," -k2 -k1 -k1

3
Cygwin має стару версію сортування. Як завжди, сторінка людини - це ваш друг.
— Charlie Martin

2
Я згоден з @CharlieMartin, вам слід перевірити сторінку довідників у вашій системі. На CentOS, яким я користувавсяsort --field-separator=';' -k2 -k1 -k3 test.csv
— Адам Порад

-6

..і якщо хтось дотримувався рішення "сортування", але тепер хоче отримати більше, ніж один унікальний запис на рядок (тобто верхню кількість X унікальних записів), як тільки ви сортуєте файл за допомогою "сортування", ви можете використовувати невеликий додаток, який я створив тут:

https://github.com/danieliversen/MiscStuff/blob/master/scripts/findTopUniques.java


2
Добре тобі! Але у вашому випадку ви можете просто використовувати cat unsorted-file | sort | uniq | head -X- коли Xце кількість перших рядків, які ви хочете вивести.
— Славік Мельцер

@SlavikMe Велике спасибі за коментар! Однак ваша пропозиція дає інший результат. Ваша пропозиція отримує перші X рядки у повністю відсортованому файлі, тоді як ми хотіли отримати перші X рядки за "ключем" (тобто якщо у вас CSV з іменами, то якщо ви сортуєте у стовпці 2 "прізвище", то ваші команди, можливо, отримають лише 3 рядки з "Алленом" як прізвищем, тоді як наші отримають "Аллен", "Бріттен", "Чарльз" тощо). Хоча дякую!
— Даніель Іверсен,

6
ви неправі. Я б запропонував спробувати команду, яку я написав, перш ніж коментувати. Зверніть увагу, що існує команда uniqв порядку труб між sortі head, яка надає унікальність для всіх відсортованих рядків безпосередньо перед вилученням верхніх рядків.
— Славік Мельцер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.