Как распечатать только уникальные строки в BASH?

Как я могу напечатать только те строки, которые появляются в файле ровно один раз? Например, для этого файла:

mountain
forest
mountain
eagle

Результат будет таким, потому что строка mountain появляется дважды:

forest
eagle
  • При необходимости строки можно отсортировать.

person Village    schedule 19.05.2014    source источник
comment
Я думаю, ты можешь использовать словарь. Вы можете посмотреть эту ссылку: stackoverflow.com/questions/1494178/   -  person    schedule 19.05.2014


Ответы (3)


Используя awk:

awk '{!seen[$0]++};END{for(i in seen) if(seen[i]==1)print i}' file
eagle
forest
person anubhava    schedule 19.05.2014
comment
Не нужно так усложнять. простая команда uniq тоже выполнит эту работу. - person Rahul; 19.05.2014
comment
1. Это не сложно и 2. Это позволяет избежать дорогостоящих sort для больших файлов. - person anubhava; 19.05.2014
comment
@anubhava Хороший awk. +1. Но для него действительно проще использовать uniq. А хранить в памяти файлы побольше - кто знает - что дороже. Обмен или сортировка. :) - person jm666; 19.05.2014
comment
@anubhava только что протестировал на 300 тыс. строк. Это awk решение в 8 раз быстрее, чем sort|uniq. - person jm666; 19.05.2014
comment
@ jm666: Большое спасибо за запуск теста и проверку того, что команда awk быстрее, чем sort|uniq. - person anubhava; 19.05.2014
comment
Поскольку мы выполняем итерацию, мы можем быстро проверить и распечатать только те, которые видны только один раз. awk '{!seen[$0]++};END{for(i in seen) if(seen[i]==1)print i}' file, но тем не менее +1. - person jaypal singh; 19.05.2014
comment
Да, конечно, это тоже можно сделать, я просто выбрал удаление, чтобы освободить память, не уверен, насколько это поможет :) - person anubhava; 19.05.2014
comment
@anubhava Это верная точка зрения, но поскольку решение есть прямо сейчас, он, вероятно, запутается, когда количество дубликатов будет в нечетных числах. Например, если вы добавите еще mountain строку, она также будет напечатана. - person jaypal singh; 19.05.2014
comment
@jaypal: А, это очень важный момент. Я обновил, как вы предложили, большое спасибо! - person anubhava; 19.05.2014
comment
@anubhava Спасибо за редактирование, и добро пожаловать. :) - person jaypal singh; 19.05.2014
comment
@ jm666 Я пробовал использовать свой .xsession-errors.old файл (129315 строк), и решение sort | uniq в 5 раз быстрее, чем это awk решение ... - person gniourf_gniourf; 19.05.2014
comment
@gniourf_gniourf sort также добавил преимущество записи кеша на диск, если память недоступна. awk не имеет этого преимущества. - person jaypal singh; 19.05.2014
comment
Я создал 803200 lines текстовый файл. Моя команда awk взяла: 1.946s, тогда как sort|uniq взяла 3.188s на моем OSX. - person anubhava; 19.05.2014
comment
моя OS X, вероятно, медленна при вводе-выводе, потому что я сделал: gsort -uR /usr/share/dict/* > words.txt (gsort - это версия сортировки GNU - для получения случайно упорядоченного файла) - получил 312123 строки. И протестировали обе команды: time sort words.txt | uniq -u >/dev/null (получено: 8,4 секунды) и time awk .... words.txt >/dev/null получено: 1,3 секунды. Итак, для меня (повторяется несколько раз) awk (почти) в 8 раз быстрее, чем sort. - person jm666; 19.05.2014

Используйте sort и uniq:

sort inputfile | uniq -u

Параметр -u заставит uniq печатать только уникальные строки. Цитата из man uniq:

   -u, --unique
          only print unique lines

Для вашего ввода он выдаст:

eagle
forest

Замечания: не забудьте sort перед uniq -u, потому что uniq работает на смежных строках. На самом деле uniq -u печатает строки, у которых нет идентичных соседних строк, но это не значит, что они действительно уникальны. Когда вы sort, все идентичные строки группируются вместе, и только те строки, которые действительно уникальны в файле, останутся после uniq -u.

person devnull    schedule 19.05.2014
comment
@jordan Не знаю. Возможно, кому-то это не понравилось. - person devnull; 19.05.2014
comment
@anubhava А ты пробовал? - person devnull; 19.05.2014
comment
Извините, я пропустил -u при копировании / вставке. - person anubhava; 19.05.2014
comment
Мне нравится простой ответ. +1 за эту простоту. - person Rahul; 19.05.2014

Вы почти получили ответ на свой вопрос:

sort filename | uniq -u

person Oliver Matthews    schedule 19.05.2014