8

Я использую Unix для сортировки файла с разделителями-запятыми с несколькими столбцами. До сих пор это прекрасно работало для сортировки данных по номерам или по алфавиту:

Файл примера перед любой сортировкой:

C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

Сортировать файл: $ sort -t ',' -k 2,2 -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

Сортированный результат:

A,Bahamas,Bahamas,Nassau,f,2
A,Canada,QC,Montreal,f,2
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1

Вот проблема: я хочу отсортировать столбец 2 на основе пользовательской сортировки, то есть я хочу сначала Соединенные Штаты, затем Канаду, а затем Багамские острова:

Желаемый вид:

A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

Есть ли способ передать unix sort пользовательский порядок сортировки, который затем можно применить? Примерно так: $ sort -t ',' -k 2,2:'United States, Canada, Bahamas' -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

Спасибо!

3 ответа3

7

Другой ответ и комментарий отвечают на вопрос в целом, вот как может выглядеть реализация:

$ cat order
Bahamas,3
Canada,2
United States,1

$ cat data
C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

$ sort -t, -k2 data | join -t, -11 -22 order - | sort -t, -k2n -k4,5 -k6r -k7nr | cut -d, -f 3,1,4-7
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
1

Вы не можете сделать это с помощью сортировки. На этом этапе вы действительно должны использовать awk/perl/your-language-of-choice. Вы можете обмануть это, хотя. Вы можете, например, использовать sed, чтобы изменить "Соединенные Штаты" на 0, "Канада" на 1 и "Багамские острова" на 2, затем выполнить числовую сортировку по этому столбцу, а затем вернуть его обратно. Или измените "Соединенные Штаты" на «Соединенные Штаты, 0» и т.д., Отсортируйте по дополнительному столбцу и затем отбросьте его.

0

Я просто написал помощник по имени csort, чтобы сделать это легко. Он добавляет в каждую строку значение по вашему выбору на основе совпадений подстроки или регулярного выражения в строке:

$ csort -t, '2=United States' X 2=Canada Y 2=Bahamas Z < tmp.csv | \
sort -t, -k1,1 -k3,3 -k4,4 -k5,5 -k6,6r -k7,7nr
X,A,United States,MA,Boston,f,0
X,B,United States,NY,New York,f,5
X,A,United States,NY,New York,f,1
X,C,United States,WA,Tacoma,f,1
Y,A,Canada,QC,Montreal,f,2
Z,A,Bahamas,Bahamas,Nassau,f,2

Обозначение 2=STR означает «соответствует, если второе поле равно STR ».

Затем вы можете при желании передать вывод через cut -c3- чтобы удалить префикс.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .