Есть ли лучшее решение для печати уникальных линий, кроме комбинации sort
и uniq
?
command-line
text-processing
Позволь мне быть
источник
источник
sort
(например, GNU coreutils) используют временные файлы и внешнюю сортировку слиянием, если ввод слишком велик для размещения в ОЗУ. И большинство других версий имеют-m
опцию, так что это можно сделать явно, разбив входные данные (например, с помощьюsplit
), отсортировав каждый чанк, а затем объединив чанкиОтветы:
Чтобы напечатать каждую одинаковую строку только одну, в любом порядке:
Для печати только уникальных строк в любом порядке:
Чтобы напечатать каждую одинаковую строку только один раз, в порядке их первого появления: (для каждой строки выведите строку, если она еще не была видна, затем в любом случае увеличьте счетчик видимых значений)
Чтобы напечатать только уникальные строки, в порядке их первого вхождения: (запишите каждую строку
seen
, а также,lines
если это первое вхождение; в конце ввода напечатайте строки в порядке вхождения, но только те, которые видны только один раз)источник
awk '!seen[$0]++ {print}'
?awk '!seen[$0]++'
, поскольку{print}
подразумевается пустой командой.Некоторые (большинство?) Версии
sort
имеют-u
флаг, который выполняетuniq
роль напрямую. Могут быть некоторые ограничения длины строки, в зависимости от реализации, но у вас уже были те, которые были с plainsort|uniq
.источник
sort -u
восходит к V7 по крайней мере.-u
ограничение длины строки в 512 символов. (На самом деле, я думаю, что где-то около Solaris 9 Sun повысил его до 5120. Хотя GNU все еще выигрывает.)Perl работает на тебя? Он может сохранять строки в исходном порядке, даже если дубликаты не являются соседними. Вы также можете написать код на Python или
awk
.Который может быть сокращен до просто
Данный входной файл:
Это дает результат:
источник
use strict;
илиuse warnings;
(на самом деле, этоstrict
наиболее актуально здесь), нет никаких претензий к использованию%lines
до того, как оно будет определено. Если запустить со стриктурами,my %lines;
перед циклом должна быть линия . Обратите внимание, что хеш есть%lines
; на один элемент хеша ссылаются с использованием$lines{$_}
нотации.sort
решения могут быть лучше для большого объема данных (ОП был обеспокоен «хранением всего файла в памяти»).sort
выполнит сортировку вне ядра, если данные больше доступной памяти.В последней части ответа, упомянутой в: Печать уникальных строк @Gilles в качестве ответа на этот вопрос, я попытался устранить необходимость использования двух хешей.
Это решение для: Для печати только уникальных строк, в порядке их первого появления:
awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'
Здесь «counter» хранит количество каждой строки, аналогичное тому, которое было обработано ранее.
В конце мы печатаем только те строки, у которых значение счетчика равно 1.
источник