Попытка сортировать по двум полям, затем сначала

Я пытаюсь сортировать по нескольким столбцам. Результаты не так ожидаемы.

Вот мои данные (people.txt):

Simon Strange 62 Pete Brown 37 Mark Brown 46 Stefan Heinz 52 Tony Bedford 50 John Strange 51 Fred Bloggs 22 James Bedford 21 Emily Bedford 18 Ana Villamor 44 Alice Villamor 50 Francis Chepstow 56 

Правильно работает следующее:

 bash-3.2$ sort -k2 -k3 <people.txt Emily Bedford 18 James Bedford 21 Tony Bedford 50 Fred Bloggs 22 Pete Brown 37 Mark Brown 46 Francis Chepstow 56 Stefan Heinz 52 John Strange 51 Simon Strange 62 Ana Villamor 44 Alice Villamor 50 

Но следующее не работает, как ожидалось:

 bash-3.2$ sort -k2 -k1 <people.txt Emily Bedford 18 James Bedford 21 Tony Bedford 50 Fred Bloggs 22 Pete Brown 37 Mark Brown 46 Francis Chepstow 56 Stefan Heinz 52 John Strange 51 Simon Strange 62 Ana Villamor 44 Alice Villamor 50 

Я пытался сортировать по фамилии, а затем по имени, но вы увидите, что Villamors не в правильном порядке. Я надеялся сортировать по фамилии, а затем, когда фамилии совпали, сортировать по имени.

Кажется, есть что-то о том, как это должно работать, я не понимаю. Я мог бы сделать это по-другому (используя awk), но я хочу понять, как это сделать.

Я использую стандартную оболочку Bash в Mac OS X.

2 Solutions collect form web for “Попытка сортировать по двум полям, затем сначала”

Ключевая спецификация, такая как -k2 означает учет всех полей от 2 до конца строки. Так Villamor 44 заканчивается до Villamor 50 . Поскольку эти два не равны, первое сравнение в sort -k2 -k1 достаточно, чтобы различать эти две строки, а второй ключ сортировки -k1 не вызывается. Если бы у двух Villamors был такой же возраст, -k1 заставил бы их сортировать по имени.

Для сортировки по одному столбцу используйте -k2,2 в качестве ключевой спецификации. Это означает использование полей от # 2 до # 2, т. Е. Только второе поле.

sort -k2 -k3 <people.txt избыточен: он эквивалентен sort -k2 <people.txt . Для сортировки по фамилиям, именам, потом возрастам

 sort -k2,2 -k1,1 <people.txt 

или эквивалентно sort -k2,2 -k1 <people.txt поскольку есть только эти три поля и разделители одинаковы. Фактически, вы получите тот же эффект от sort -k2,2 <people.txt , потому что sort использует всю строку в качестве последнего средства, когда все ключи в подмножестве строк идентичны.

Также обратите внимание, что разделителем полей по умолчанию является переход между непустым и пустым, поэтому ключи будут включать в себя ведущие пробелы (в вашем примере для первой строки первый ключ будет "Emily" , но второй ключ " Bedford" . Добавьте опцию -b чтобы снять эти пробелы:

 sort -b -k2,2 -k1,1 

Это также можно сделать по принципу «ключ», добавив флаг b в конце спецификации запуска ключа:

 sort -k2b,2 -k1,1 <people.txt 

Но что-то, о чем нужно помнить: как только вы добавляете один такой флаг в спецификацию ключа, глобальные флаги (например, -n , -r …) больше не применяются к ним, поэтому лучше избегать смешивания флажков с ключом и глобальные флаги.

С помощью GNU sort вы делаете это так, не уверены в MacOS:

 sort -k2,2 -k1 <people.txt 

Обновление в соответствии с комментарием. Цитата из man sort :

  -k, --key=KEYDEF sort via a key; KEYDEF gives location and type KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a field number and C a character position in the field; both are origin 1, and the stop position defaults to the line's end. 
  • команда сортировки не работает в этом файле
  • сортировать каждый столбец (поле) в файле отдельно
  • Как отсортировать эти строки?
  • Можно сортировать сортировку 1 2 3 4..9 вместо 1 10 11 12 .. 2 20
  • Почему этот вид игнорирует префикс +/-?
  • сортировать в unix на большом файле
  • Сортировка строк на основе номера переменной ширины в фиксированном положении
  • Сначала попытка сортировки по двум полям - это второй критерий
  • Сортировка на основе последнего появления символа
  • Как сортировать смешанные тексты и цифры (например, имена хостов)?
  • Масштабируемость «sort -u» для гигантских файлов
  • Interesting Posts

    Как создать ad-hoc-соединение?

    Cron, чтобы проверить, запущен ли PHP-скрипт, если он не запускается

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

    Диспетчеру дисплея mdm не удается загрузить среду рабочего стола

    Установить Gvim после vim

    Как отключить ввод движения мыши, если оставить кнопки мыши включенными?

    используя wget для загрузки всех аудиофайлов (более 100 000 страниц на wikia)

    Как вы будете использовать SSH в другой учетной записи root?

    Пакет ssmtp отсутствует в debian jessie – альтернативы?

    Использование Sed с регулярным выражением

    Как в реальном времени отображать номер из запущенного файла журнала или терминала

    Могу ли я запустить команду после того, как пользователь использует Ctrl-C, чтобы убить команду?

    Ошибка ssh daemon: sshd должен быть собственным

    Emscripten принципиально несовместим с clang on linux

    поддержка tmux, TERM и 256 цветов

    Linux и Unix - лучшая ОС в мире.