Відсортуйте файл 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.