Periksa semua baris file unik

11

Saya memiliki file teks yang berisi baris seperti ini:

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

Bagaimana saya bisa yakin akan keunikan setiap baris?

CATATAN: Tujuannya adalah untuk menguji file, bukan untuk memodifikasinya jika ada duplikat baris.

snr
sumber
1
Menautkan: unix.stackexchange.com/q/76049/117549
Jeff Schaller
1
Apakah Anda ingin memeriksa apakah semua baris unik, atau Anda ingin menghapus duplikat?
8bittree
1
@ 8bittree - ingin memastikan keunikan
snr

Jawaban:

24
[ "$(wc -l < input)" -eq "$(sort -u input | wc -l)" ] && echo all unique
Jeff Schaller
sumber
Persis apa yang akan saya katakan, kecuali dengan uniqbukansort -u
Nonny Moose
1
Jika input belum diurutkan, uniqakan menjadi kesalahan besar; itu hanya menghilangkan garis yang berdekatan!
alexis
1
Jika seseorang tertarik pada pelakunya, sort <file> | uniq -dakan mencetak duplikatnya.
Rolf
25

Solusi awk:

awk 'a[$0]++{print "dupes"; exit(1)}' file && echo "no dupes"
iruvar
sumber
4
+1 Jawaban yang diterima membaca seluruh file dua kali, sementara ini berhenti segera setelah menemukan garis duplikat dalam satu kali dibaca. Ini juga akan bekerja dengan input yang disalurkan, sementara file kebutuhan lainnya dapat dibaca kembali.
JoL
Tidak bisakah Anda mendorong ke echodalam END?
Ignacio Vazquez-Abrams
2
@ IgnacioVazquez-Abrams Benar-benar tidak ada gunanya dalam gema. Melakukan && echoatau || echomerupakan konvensi dalam jawaban untuk menunjukkan bahwa suatu perintah melakukan hal yang benar dengan kode status keluar. Yang penting adalah exit(1). Idealnya, Anda akan menggunakan ini seperti if has_only_unique_lines file; then ..., bukan if [[ $(has_only_unique_lines file) = "no dupes" ]]; then ..., itu konyol.
JoL
2
Di mana jawaban lain membaca file dua kali untuk menghemat memori, ini akan membaca seluruh file menjadi memori, jika tidak ada dupes.
Kusalananda
1
@ Kusalananda Meskipun ini akan membaca seluruh file ke dalam memori ketika tidak ada dupes, menggunakan sortkehendak juga, terlepas dari apakah ada dupes atau tidak, kan? Bagaimana cara menghemat memori?
JoL
21

Menggunakan sort/ uniq:

sort input.txt | uniq

Untuk memeriksa hanya garis duplikat, gunakan -dopsi untuk uniq. Ini hanya akan menampilkan baris yang duplikat, jika tidak ada yang tidak akan menunjukkan apa-apa:

sort input.txt | uniq -d
jesse_b
sumber
Ini goto saya. Tidak yakin apa yang ditawarkan, jawaban dengan suara lebih tinggi menawarkan yang satu ini tidak.
user1717828
1
Ini alternatif yang baik untuk menghapus duplikat.
snr
1
Ini tidak melakukan apa yang dia inginkan. Dia ingin tahu apakah ada duplikat, bukan menghapusnya.
Barmar
@Barmar: Meskipun tampaknya seperti itu, pertanyaannya masih belum jelas. Serta komentar OP yang berusaha menjelaskannya.
jesse_b
Ada suntingan yang tertunda yang menambahkan lebih banyak klarifikasi.
Barmar
5

TLDR

Pertanyaan aslinya tidak jelas, dan membaca bahwa OP hanya menginginkan versi unik dari isi file. Itu ditunjukkan di bawah ini. Dalam bentuk pertanyaan sejak diperbarui, OP sekarang menyatakan bahwa ia hanya ingin tahu apakah isi file itu unik atau tidak.


Uji apakah konten file unik atau tidak

Anda cukup menggunakan sortuntuk memverifikasi apakah file itu unik atau mengandung duplikat seperti:

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

Contoh

Katakanlah saya punya dua file ini:

file sampel duplikat
$ 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
file sampel unik
$  cat uniq_input.txt
A
B
C
D

Sekarang ketika kami menganalisis file-file ini, kami dapat mengetahui apakah mereka unik atau mengandung duplikat:

uji duplikat file
$ sort -uC dup_input.txt && echo "unique" || echo "duplicates"
duplicates
uji file unik
$ sort -uC uniq_input.txt && echo "unique" || echo "duplicates"
unique

Pertanyaan asli (konten unik file)

Dapat dilakukan hanya dengan 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
sumber
3

Saya biasanya sortfile, lalu gunakan uniquntuk menghitung jumlah duplikat, maka saya sortsekali lagi melihat duplikat di bagian bawah daftar.

Saya menambahkan satu duplikat ke contoh yang Anda berikan:

$ 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

Karena saya belum membaca halaman manual untuk uniqsementara waktu, saya mengambil cepat mencari alternatif. Berikut ini menghilangkan kebutuhan untuk jenis kedua, jika Anda hanya ingin melihat duplikat:

$ sort thread.file | uniq -d
This is a thread  139737505302272
Carlos Hanson
sumber
Itu memang alternatif yang bagus. #rez
SNR
2

Jika tidak ada duplikat, semua baris unik:

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

Deskripsi: Mengurutkan baris file untuk membuat garis yang diulang berturut-turut (urut)
Ekstrak semua baris berurutan yang sama (uniq -d).
Jika ada output dari perintah di atas ( [...]), maka ( &&) cetak pesan.

NotAnUnixNazi
sumber
2

Ini tidak akan lengkap tanpa jawaban Perl!

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

Ini akan mencetak setiap baris non-unik sekali: jadi jika tidak mencetak apa-apa, maka file memiliki semua baris unik.

frapadingue
sumber
1

Menggunakan cmpdan sortdalam bash:

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

atau

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

Ini akan mengurutkan file dua kali, sama seperti jawaban yang diterima.

Kusalananda
sumber