Сортировка и uniq в оболочке Linux - PullRequest
45 голосов
/ 01 августа 2010

В чем разница между следующими командами?

sort -u FILE

sort FILE | uniq

Ответы [ 6 ]

75 голосов
/ 01 августа 2010

Использование sort -u делает меньше операций ввода-вывода, чем sort | uniq, но конечный результат тот же. В частности, если файл достаточно велик для того, чтобы sort должен был создавать промежуточные файлы, вполне вероятно, что sort -u будет использовать немного меньшее или немного меньшее количество промежуточных файлов, поскольку это может устранить дубликаты при сортировке каждого набора. Если данные сильно дублируют друг друга, это может быть полезно; если на самом деле есть несколько дубликатов, это не будет иметь большого значения (безусловно, эффект производительности второго порядка по сравнению с эффектом первого порядка канала).

Обратите внимание, что есть время, когда уместен трубопровод. Например:

sort FILE | uniq -c | sort -n

Это сортирует файл по порядку количества вхождений каждой строки в файле, причем самые повторяющиеся строки появляются последними. (Меня не удивит, что эта комбинация, идиоматическая для Unix или POSIX, может быть объединена в одну сложную команду sort с сортировкой GNU.)

Бывают случаи, когда важно не использовать трубу. Например:

sort -u -o FILE FILE

Это сортирует файл «на месте»; то есть выходной файл указывается с помощью -o FILE, и эта операция гарантированно безопасна (файл читается перед перезаписью для вывода).

10 голосов
/ 01 августа 2010

Есть одно небольшое отличие: код возврата.

Дело в том, что, если не установлено shopt -o pipefail, код возврата переданной команды будет кодом возврата последней.И uniq всегда возвращает ноль (успех).Попробуйте проверить код завершения, и вы увидите что-то вроде этого (pipefail здесь не задано):

pavel@lonely ~ $ sort -u file_that_doesnt_exist ; echo $?
sort: open failed: file_that_doesnt_exist: No such file or directory
2
pavel@lonely ~ $ sort file_that_doesnt_exist | uniq ; echo $?
sort: open failed: file_that_doesnt_exist: No such file or directory
0

В остальном команды эквивалентны.

8 голосов
/ 24 августа 2012

Осторожно! Хотя это правда, что «sort -u» и «sort | uniq» эквивалентны, любые дополнительные параметры сортировки могут нарушить эквивалентность. Вот пример из руководства coreutils:

Например, `sort -n -u 'проверяет только значение исходной числовой строки при проверке уникальности, тогда как' sort -n | uniq 'проверяет всю строку.

Точно так же, если вы сортируете по ключевым полям, тест уникальности, используемый сортировкой, не обязательно будет больше рассматривать всю строку. В прошлом, будучи укушенным этой ошибкой, в наши дни я склонен использовать «sort | uniq» при написании сценариев Bash. Я бы предпочел более высокие издержки ввода-вывода, чем риск, что кто-то в магазине не узнает об этой конкретной ловушке, когда они изменят мой код, добавив дополнительные параметры сортировки.

6 голосов
/ 01 августа 2010

sort -u будет немного быстрее, потому что не нужно передавать результат между двумя командами

см. Также мой вопрос по теме: вызов uniq и сортировка в разных порядках в оболочке

2 голосов
/ 01 августа 2010

Ничего, они дадут тот же результат

1 голос
/ 02 августа 2010

Я работал на некоторых серверах, где sort не поддерживает опцию '-u'. там мы должны использовать

sort xyz | uniq
...