Perintah Unix untuk memeriksa apakah ada dua baris dalam file yang sama?

24

Apakah ada perintah unix yang dapat memeriksa apakah ada dua baris dalam file yang sama?

Untuk misalnya Pertimbangkan file sentences.txt

This is sentence X
This is sentence Y
This is sentence Z
This is sentence X
This is sentence A
This is sentence B

Kami melihat kalimat itu

This is sentence X

diulangi.

Apakah ada perintah yang dapat dengan cepat mendeteksi ini, sehingga saya mungkin dapat menjalankannya seperti ini -

$ cat sentences.txt | thecommand
Line 1:This is sentence X
Line 4:This is sentence X
Kode biru
sumber

Jawaban:

40

Ini adalah salah satu cara untuk mendapatkan hasil persis yang Anda cari:

$ grep -nFx "$(sort sentences.txt | uniq -d)" sentences.txt 
1:This is sentence X
4:This is sentence X

Penjelasan:

Bagian dalam $(sort sentences.txt | uniq -d)mencantumkan setiap baris yang muncul lebih dari satu kali. Bagian luar grep -nFxmencari kembali sentences.txtuntuk -xpencocokan tepat ke salah satu dari garis-garis ini -Fdan menambahkan nomor baris mereka-n

grebneke
sumber
Hasil edit Anda nyaris tidak mengalahkan saya karena memposting jawaban yang sama persis. +1
casey
Jadi sintaks $ (perintah) berfungsi sebagai semacam pengganti?
CodeBlue
2
@ KodeBiru - ya. Ini disebut Substitusi Perintah
grebneke
8
sort sentences.txt | uniq -d | grep -nFxf - sentences.txtakan menjadi sedikit lebih efisien dan akan menghindari arg list too longmasalah potensial .
Stéphane Chazelas
10

Bukan yang Anda inginkan, tetapi Anda dapat mencoba menggabungkan sortdan uniq -c -d:

aularon@aularon-laptop:~$ cat input
This is sentence X
This is sentence Y
This is sentence Z
This is sentence X
This is sentence A
This is sentence B

aularon@aularon-laptop:~$ sort input | uniq -cd
      2 This is sentence X
aularon@aularon-laptop:~$ 

2di sini adalah jumlah duplikasi yang ditemukan untuk baris, dari man uniq:

   -c, --count
          prefix lines by the number of occurrences

   -d, --repeated
          only print duplicate lines
aularon
sumber
6

JIKA isi file sesuai dengan memori awkbaik untuk ini. Satu-liner standar di comp.lang.awk (Saya tidak bisa mencari contoh dari mesin ini tapi ada beberapa setiap bulan) untuk mendeteksi ada duplikasi awk 'n[$0]++'yang menghitung kemunculan setiap nilai baris dan mencetak setiap kejadian (s) selain yang pertama, karena tindakan default adalah print $0.

Untuk menampilkan semua kejadian termasuk yang pertama, dalam format Anda, tetapi mungkin dalam urutan campuran ketika lebih dari satu nilai digandakan, menjadi sedikit lebih rumit:

awk <sentences.txt ' !($0 in n) {n[$0]=NR;next} \
    n[$0] {n[$0]=0; print "Line "n[$0]":"$0} \
    {print "Line "NR":"$0} '

Ditampilkan dalam beberapa baris untuk kejelasan, Anda biasanya berjalan bersama dalam penggunaan nyata. Jika Anda sering melakukan ini, Anda dapat meletakkan awkskrip dalam file awk -f, atau tentu saja semuanya dalam skrip shell. Seperti yang paling sederhana awkini dapat dilakukan dengan sangat mirip perl -n[a].

dave_thompson_085
sumber