У меня есть потенциально большие файлы, которые нужно отсортировать по 1-n ключам. Некоторые из этих клавиш могут быть числовыми, а некоторые - нет. Это столбчатый файл с фиксированной шириной, поэтому разделителей нет.
Есть ли хороший способ сделать это с помощью сортировки Unix? С одним ключом это так же просто, как использовать '-n'. Я прочитал справочную страницу и немного поискал в Google, но не нашел хорошего примера. Как бы я пошел для достижения этой цели?
Примечание: я исключил Perl из-за потенциального размера файла. Это было бы последнее средство.
Используйте -k
опцию (или --key=POS1[,POS2]
). Он может появляться несколько раз, и каждый ключ может иметь глобальные параметры (например, n
для числовой сортировки).
Опция -k - это то, что вы хотите.
-k 1.4,1.5n -k 1.14,1.15n
Использовал бы позиции символов 4-5 в первом поле (это все одно поле для фиксированной ширины) и сортировал бы численно в качестве первого ключа.
Второй ключ будет также символами 14-15 в первом поле.
(редактировать)
Пример (все, что у меня есть, это DOS / Cygwin Handy):
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 нужно отсортировать.
Я верю в вашем случае что-то вроде
sort -t@ -k1.1,1.4 -k1.5,1.7 ... <inputfile
будет работать лучше. @ - это разделитель полей, убедитесь, что это символ, который нигде не отображается. тогда ваш вход считается состоящим из одного столбца.
Редактировать: по-видимому, clintp уже дал аналогичный ответ, извините. Как он указывает, флаги 'n' и 'r' могут быть добавлены к каждой опции -k ....
Будьте осторожны, хотя:
Если вы хотите отсортировать файл в первую очередь по полю 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)
sort -k 3,3nr -k 2,2
-k2
должен быть нелогичный интерфейс: -k2,2
запятая -k2,
должна быть «волшебный конец строки по умолчанию или что-то еще». Обратите внимание, что может также потребоваться стабилизировать сортировку с помощью -s
переключателя, чтобы строки с одинаковым ранжированием также сохраняли свой исходный относительный порядок в выходных данных.
Я просто хочу добавить несколько советов, когда вы используете сортировку, будьте осторожны с вашей локалью, которая влияет на порядок сравнения ключей. Я обычно явно использую LC_ALL = C, чтобы сделать локаль, что я хочу.
Здесь можно отсортировать различные столбцы в 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