Как напечатать уникальные значения в порядке появления? - PullRequest
5 голосов
/ 15 марта 2020

Я пытаюсь получить уникальные значения из списка ниже, но оставляю уникальные значения в исходном порядке.

Это порядок появления.

group
swamp
group
hands
swamp
pipes
group
bellyful
pipes
swamp
emotion
swamp
pipes
bellyful
after
bellyful

Я пытался объединить команды sort и uniq, но вывод сортируется по алфавиту, и если я не использую команда сортировки, команда uniq не работает.

$ sort file | uniq
after
bellyful
emotion
group
hands
pipes
swamp

и мой вывод будет выглядеть следующим образом

group
swamp
hands
pipes
bellyful
emotion
after

Как я могу это сделать?

1 Ответ

7 голосов
/ 15 марта 2020

Короткий, застрявший вызов awk выполнит работу. Мы создадим ассоциативный массив и будем считать каждый раз, когда увидим слово:

$ awk '!count[$0]++' file
group
swamp
hands
pipes
bellyful
emotion
after

Объяснение:

  1. Awk обрабатывает файл по одной строке за раз и $0 - текущая строка.
  2. count - это строки сопоставления ассоциативного массива с количеством раз, которое мы их видели. Awk не против, чтобы мы обращались к неинициализированным переменным. Он автоматически делает count массивом и устанавливает элементы равными 0 при первом обращении к ним.
  3. Мы увеличиваем счетчик каждый раз, когда видим конкретную строку.
  4. Мы хотим получить общее значение Выражение для оценки истинно в первый раз, когда мы видим слово, и ложно каждый раз. Когда это правда, строка печатается. Когда оно ложно, строка игнорируется. Первый раз, когда мы видим слово count[$0], это 0, и мы отрицаем его до !0 == 1. Если мы снова видим, что слово count[$0] является положительным, и отрицание дает 0.
  5. Почему значение true означает, что строка напечатана? Общий синтаксис, который мы используем: expr { actions; }. Когда выражение верно, действия предпринимаются. Но действия могут быть опущены; действие по умолчанию, если мы не пишем, - { print; }.
...