Thank you for reading this post, don't forget to subscribe!
Команда uniq в Unix и Linux используется для фильтрации дублированного текста. Она может использоваться сама по себе, но обычно используется вместе с другими командами, такими как определение избыточной информации в файле.
Вот синтаксис команды uniq:
1 |
uniq [options] <input-file> <output-file> |
Когда вы запускаете uniq без параметров, она будет использоваться с stdin и stdout для ввода и вывода.
Хотя использование stdin возможно при использовании буфера обмена (копирование/вставка), но это не самое практичное использование.
Вместо этого вы, вероятно, захотите использовать эту команду для файла, который, как вы подозреваете, содержит дублирующую информацию.
Одним из ограничений команды uniq является то, что она будет идентифицировать только дубликаты, которые находятся рядом друг с другом в файле. Это довольно просто, но позвольте нам показать вам пример, чтобы вы могли увидеть его в действии.
1 2 3 4 5 6 7 |
[andreyex@fedora ~]$ cat debian.txt debian debian centos centos debian centos |
1 2 3 4 5 |
[andreyex@fedora ~]$ uniq debian.txt debian centos debian centos |
Таким образом, вы сразу знаете, что не можете доверять программе, чтобы идентифицировать каждый дубликат самостоятельно. Есть несколько способов обойти это, и обычно это происходит с помощью команды sort .
Мы покажем вам это позже в этой статье. Во-первых, позвольте нам показать некоторые примеры, чтобы познакомить вас с ‘uniq’, прежде чем смешивать другие команды и, возможно, сбивать с толку.
7 примеров команды uniq в Linux
Мы использовали настоящий системный журнал, но редактировали его для демонстрационных целей. Большая часть файла уже отсортирована в соседнем порядке, но мы оставили пару строк «не на своем месте», чтобы показать функциональность команды uniq.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device is a keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device is a keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device removed /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0 /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network |
Пример 1. Использование команды uniq по умолчанию
Хотя мы уже показали вам это, давайте посмотрим на наш пример файла с использованием синтаксиса по умолчанию.
1 2 3 4 5 6 7 8 9 10 |
[andreyex@fedora ~]$ uniq sample_log_file.txt /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device is a keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device removed /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0 /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network |
Вы можете видеть, что много повторяющихся строк объединены, но они все еще содержат избыточную информацию. Это связано с функциональным ограничением, которое мы уже описывали. Давайте рассмотрим еще несколько примеров и рассмотрим некоторые параметры, встроенные в утилиту командной строки ‘uniq’.
Пример 2: Вывести отфильтрованные результаты в файл назначения
Вы можете сохранить этот вывод, чтобы вы могли легко отредактировать или сохранить его. Вы можете направить наш вывод в отдельный файл вместо обычного stdout (терминала). Важно отметить, что вы не можете использовать этот формат для переопределения исходного файла.
1 |
[andreyex@fedora ~]$ uniq sample_log_file.txt uniq_log_output.txt |
Вот содержимое выходного файла:
1 2 3 4 5 6 7 8 9 10 |
[andreyex@fedora ~]$ cat uniq_log_output.txt /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device is a keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device removed /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0 /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network |
Пример 3: Использование ‘-c’, чтобы получить количество повторных строк
Этот вариант довольно понятен. Программа добавит счет в начало каждой строки.
1 2 3 4 5 6 7 8 9 10 |
[andreyex@fedora ~]$ uniq sample_log_file.txt -c 2 /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. 2 /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device is a keyboard 1 /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device removed 2 /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard 5 /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. 1 /usr/lib/gdm3/gdm-x-session[1242]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0 7 /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. 1 PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms 8 wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network |
Пример 4: печатать только повторяющиеся строки с ‘-d’
Как видите, отображаются только строки, которые дублируются по всему файлу, если вы используете опцию -d команды uniq.
1 2 3 4 5 6 7 |
[andreyex@fedora ~]$ uniq sample_log_file.txt -d /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device is a keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. /usr/lib/gdm3/gdm-x-session[1242]: (II) This device may have been added with another device file. wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network |
Пример 5: печатать только уникальные строки с ‘-u’
Здесь вы получите обратный вывод предыдущей команды. Ни одна из этих команд не повторяется в файле.
1 2 3 4 |
[andreyex@fedora ~]$ uniq sample_log_file.txt -u /usr/lib/gdm3/gdm-x-session[1242]: (II) event9 - Intel HID events: device removed /usr/lib/gdm3/gdm-x-session[1242]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0 PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms |
Пример 6: Игнорировать поля или символы с помощью uniq [‘-f’ и ‘-s’]
Это действительно два примера, но функции практически идентичны. Мы объясняем, как они работают, а затем предоставляем некоторую ясность в различиях между ними двумя.
Каждый из них использует следующий синтаксис
1 2 3 4 |
Skip fields with: uniq <source_file> -f N Skip characters with: uniq <source_file> -s N |
В каждом из этих примеров «N» – это количество элементов, которые вы хотите пропустить. Когда вы пропустите это количество элементов, uniq начнет сравнение в этой точке, а не сравнивает всю строку.
Опция ‘f’ пропустит назначенное количество полей. Поля будут интерпретироваться с использованием пробела.
1 2 3 4 5 6 7 8 9 |
[andreyex@fedora ~]$ cat field_separated_values.txt blue fish blue fish blue fish blue class red fish green fish two class two class |
Если вы хотите использовать команду uniq во втором столбце, вам придется пропустить первое поле следующим образом:
1 2 3 4 5 |
[andreyex@fedora ~]$ uniq -f1 field_separated_values.txt blue fish blue class red fish two class |
Как вы можете видеть, для одной и той же строки требуются «red fish» и «green fish», поскольку первое поле (с цветами) было проигнорировано. Если вы используете здесь опцию count, она покажет количество найденных уникальных строк:
1 2 3 4 5 |
[andreyex@fedora ~]$ uniq -f1 -c field_separated_values.txt 3 blue fish 1 blue class 2 red fish 2 two class |
Зачем вам это нужно? Мы дадим вам практический сценарий. Многие файлы журналов имеют временную метку в начале строк. Если вы хотите найти в таком файле только уникальные строки, вы можете пропустить первое поле с отметкой времени с параметром -f.
Точно так же вы можете пропустить определенное количество символов.
1 2 |
[andreyex@fedora ~]$ uniq -s 10 field_separated_values.txt blue fish |
Пример 7. Используйте ‘-w’, чтобы сравнить только N символов
Параметр ‘-w’ позволяет нам указать точное количество символов, которое будет использоваться в нашем сравнении.
Если вы использовали файл журнала для предыдущих примеров, это нормально. Мы хотели сделать текст сравнения немного проще, чтобы избежать путаницы. Если нет, давайте вернемся назад и посмотрим, что произойдет, если вы используете только первые символы для поиска дубликатов.
1 2 3 4 |
[andreyex@fedora ~]$ uniq -w 4 sample_log_file.txt /usr/lib/gdm3/gdm-x-session[1242]: (II) No input driver specified, ignoring this device. PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms wpa_supplicant[754]: RRM: Ignoring radio measurement request: Not RRM network |
Все строки, начинающиеся с «/usr», теперь обозначаются как «одинаковые» с точки зрения программы.
Это может оказаться полезным, если вы ищете конкретное событие журнала.
Бонус: избегайте неполных совпадений, используя «sort» и «uniq» одновременно.
Вы можете запускать эти команды отдельно для достижения того же эффекта, но если вы никогда не использовали конвейер (символ |) в Linux, это отличный способ узнать о них.
Вы можете использовать каналы для комбинирования различных команд, чтобы сэкономить нам нажатия клавиш и улучшить наш рабочий процесс. Команды будут выполняться в порядке их ввода.
Это пример ввода, который мы собираемся использовать:
1 2 3 4 5 6 7 8 9 10 |
[andreyex@fedora ~]$ cat debian.txt debian centos centos debian debian fedora debian fedora |
Теперь давайте отсортируем входной файл и затем используем команду uniq. Команда sort переупорядочивает текст так, что все элементы сначала располагаются в соседнем порядке. Затем, когда команда uniq запущена, она находит только 3 уникальные строки в файле.
1 2 3 4 |
[andreyex@fedora ~]$ sort debian.txt | uniq debian fedora centos |
Если вы измените порядок, все изменится. Выполнение команды ‘uniq’ сначала идентифицирует только смежные дубликаты, а затем они будут отсортированы в алфавитном порядке с помощью команды ‘sort’.
1 2 3 4 5 6 7 |
[andreyex@fedora ~]$ uniq debian.txt | sort debian debian debian fedora fedora centos |
Каналы позволяют нам запускать несколько команд одновременно, но важно учитывать их порядок.
Обратите внимание, что содержимое файла остается неизменным так же, как и при отдельном запуске команд. Соединение двух команд вместе также сохраняет результаты в «памяти» системы. Если вы запускаете их отдельно, вы не сможете получить эти результаты, пока не создадите новый файл и не используете его для перезаписи содержимого оригинала перед выполнением второй команды.