Проверьте все строки файла уникальны

11

У меня есть текстовый файл, содержащий такие строки:

This is a thread  139737522087680
This is a thread  139737513694976
This is a thread  139737505302272
This is a thread  139737312270080
.
.
.
This is a thread  139737203164928
This is a thread  139737194772224
This is a thread  139737186379520

Как я могу быть уверен в уникальности каждой строки?

ПРИМЕЧАНИЕ . Цель состоит в том, чтобы протестировать файл, а не изменять его, если присутствуют повторяющиеся строки.

ОСШ
источник
1
Ссылка
Джефф Шаллер
1
Вы хотите проверить, все ли строки уникальны, или вы хотите удалить дубликаты?
8bittree
1
@ 8bittree - желание просто быть уверенным , уникальность
ОСШ

Ответы:

24
[ "$(wc -l < input)" -eq "$(sort -u input | wc -l)" ] && echo all unique
Джефф Шаллер
источник
Именно то , что я бы сказал, за исключением uniqвместоsort -u
Нонны Муз
1
Если вход еще не отсортирован, uniqбудет большая ошибка; он только дедуплицирует соседние строки!
Алексис
1
Если кто-то заинтересован в виновниках, sort <file> | uniq -dон напечатает дубликаты.
Рольф
25

Awk решение:

awk 'a[$0]++{print "dupes"; exit(1)}' file && echo "no dupes"
Iruvar
источник
4
+1 Принятый ответ считывает весь файл дважды, при этом он останавливается, как только встречается повторяющаяся строка в одном чтении. Это также будет работать с канальным вводом, в то время как другим нужны файлы, которые он может перечитать.
JoL
Не могли бы вы засунуть echoв END?
Игнасио Васкес-Абрамс
2
@ IgnacioVazquez-Abrams Там действительно нет смысла в эхо. Выполнение && echoили || echoявляется соглашением в ответах, указывающим, что команда правильно поступает с кодом состояния выхода. Важной вещью является exit(1). В идеале, вы бы использовали это как if has_only_unique_lines file; then ..., нет if [[ $(has_only_unique_lines file) = "no dupes" ]]; then ..., это было бы глупо.
JoL
2
Если другие ответы читают файл дважды, чтобы сохранить память, он будет считывать весь файл в память, если нет дубликатов.
Кусалананда
1
@Kusalananda Хотя этот файл будет считан в память целиком, когда нет дубликатов, также sortбудет использоваться воля, независимо от того, есть ли дубли или нет, верно? Как это экономит память?
JoL
21

Используя sort/ uniq:

sort input.txt | uniq

Для проверки только на наличие дублирующих строк используйте -dопцию uniq. Это покажет только дубликаты строк, если нет, то ничего не будет показано:

sort input.txt | uniq -d
jesse_b
источник
Это моё goto. Не уверен, что другие ответы с более высоким голосом предлагают, что этот не делает.
user1717828
1
Это хорошая альтернатива для удаления дубликатов.
ОСШ
1
Это не делает то, что он хочет. Он хочет знать , есть ли дубликаты, а не удалять их.
Бармар
@ Бармар: Хотя кажется, что вопрос до сих пор неясен. А также комментарий ОП, пытающийся прояснить это.
jesse_b
Существует ожидающее редактирование, которое добавляет больше пояснений.
Бармар
5

TLDR

Первоначальный вопрос был неясен, и прочитал, что OP просто хотел уникальную версию содержимого файла. Это показано ниже. В обновленной форме вопроса ОП теперь заявляет, что он / она просто хочет знать, является ли содержимое файла уникальным или нет.


Проверьте, является ли содержимое файла уникальным или нет

Вы можете просто использовать, sortчтобы проверить, является ли файл уникальным или содержит дубликаты, например:

$ sort -uC input.txt && echo "unique" || echo "duplicates"

пример

Скажем, у меня есть эти два файла:

дубликат файла образца
$ cat dup_input.txt
This is a thread  139737522087680
This is a thread  139737513694976
This is a thread  139737505302272
This is a thread  139737312270080
This is a thread  139737203164928
This is a thread  139737194772224
This is a thread  139737186379520
уникальный образец файла
$  cat uniq_input.txt
A
B
C
D

Теперь, когда мы анализируем эти файлы, мы можем сказать, являются ли они уникальными или содержат дубликаты:

файл тестовых дубликатов
$ sort -uC dup_input.txt && echo "unique" || echo "duplicates"
duplicates
проверить уникальный файл
$ sort -uC uniq_input.txt && echo "unique" || echo "duplicates"
unique

Оригинальный вопрос (уникальное содержимое файла)

Может быть сделано только с sort:

$ sort -u input.txt
This is a thread  139737186379520
This is a thread  139737194772224
This is a thread  139737203164928
This is a thread  139737312270080
This is a thread  139737505302272
This is a thread  139737513694976
This is a thread  139737522087680
SLM
источник
3

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

Я добавил один дубликат к предоставленным вами примерам:

$ sort thread.file | uniq -c | sort
      1 This is a thread  139737186379520
      1 This is a thread  139737194772224
      1 This is a thread  139737203164928
      1 This is a thread  139737312270080
      1 This is a thread  139737513694976
      1 This is a thread  139737522087680
      2 This is a thread  139737505302272

Поскольку я uniqнекоторое время не читал справочную страницу , я быстро рассмотрел любые альтернативы. Следующее устраняет необходимость во второй сортировке, если вы просто хотите увидеть дубликаты:

$ sort thread.file | uniq -d
This is a thread  139737505302272
Карлос Хансон
источник
Это действительно хорошая альтернатива. #rez
snr
2

Если дубликатов нет, все строки уникальны:

[ "$(sort file | uniq -d)" ] && echo "some line(s) is(are) repeated"

Описание: Сортировка строк файла, чтобы сделать повторяющиеся строки подряд (sort)
Извлечь все последовательные строки, которые равны (uniq -d).
Если есть какой-либо вывод команды выше ( [...]), то ( &&) выведите сообщение.

NotAnUnixNazi
источник
2

Это не будет полным без ответа Perl!

$ perl -ne 'print if ++$a{$_} == 2' yourfile

Это напечатает каждую неуникальную строку один раз: поэтому, если она ничего не печатает, то в файле есть все уникальные строки.

frapadingue
источник
1

Использование cmpи sortв bash:

cmp -s <( sort file ) <( sort -u file ) && echo 'All lines are unique'

или

if cmp -s <( sort file ) <( sort -u file )
then
    echo 'All lines are unique'
else
    echo 'At least one line is duplicated'
fi

Это будет отсортировать файл дважды, как и принятый ответ.

Кусалананда
источник