Jika tujuan Anda adalah menemukan baris yang umum atau tidak umum, comm
akan menjadi perintah masuk saya di sini.
Ini membandingkan dua file dan menunjukkan —dalam tiga kolom— baris yang unik untuk file 1, baris yang unik untuk file 2 dan baris yang muncul di kedua file, masing-masing. Anda dapat melewatinya untuk menekan semua output ini juga. Misal comm -1 file1 file2
akan menekan kolom pertama, hal-hal unik untuk file1. comm -12 file1 file2
hanya akan menunjukkan hal-hal di kedua file.
Ada satu peringatan besar: input harus diurutkan. Kita bisa mengatasi ini.
Ini akan menunjukkan kepada Anda segala sesuatu dalam abc yang tidak dalam mno:
comm -23 <(sort abc.txt) <(sort mno.txt)
Dan Anda bisa menyalurkannya ke wc -l
untuk mendapatkan hitungan.
Alasan saya mengikutinya comm
adalah bahwa begitu file diurutkan, perbandingan berdampingan adalah komputasi yang sangat sederhana. Jika Anda berurusan dengan jutaan ini, itu akan membuat perbedaan.
Ini dapat ditunjukkan dengan beberapa file tiruan. Saya memiliki komputer yang cukup cepat sehingga untuk menunjukkan perbedaan antara pendekatan, saya perlu set sampel yang cukup besar. Saya telah menggunakan 10 juta string 10-char per file.
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > abc.txt
$ cat /dev/urandom | tr -dc '0-9' | fold -w 10 | head -10000000 > mno.txt
$ time comm -23 <(sort abc.txt) <(sort mno.txt) | wc -l
... 0m10.653s
$ time grep -Fcxv -f abc.txt mno.txt
... 0m23.920s
$ time grep -Fcwv -f abc.txt mno.txt
... 0m40.313s
$ time awk 'NR==FNR{a[$0]++};NR!=FNR && a[$0]' abc.txt mno.txt | wc -l
... 0m12.161s
Pemilahan adalah yang paling banyak menghabiskan waktu di tambang. Jika kami berpura-pura bahwa abc.txt statis, kami dapat mengurutkannya terlebih dahulu dan itu membuat perbandingan di masa mendatang jauh lebih cepat:
$ sort abc.txt abc-sorted.txt
$ time comm -23 abc-sorted.txt <(sort mno.txt) | wc -l
... 0m7.426s
Anda mungkin melihat ini dan menganggap beberapa detik tidak relevan tetapi saya harus menyoroti bahwa ini berjalan pada mesin high-end. Jika Anda ingin melakukan ini pada (misalnya) Raspberry Pi 3, Anda akan melihat perputaran jauh lebih lambat dan perbedaan akan meningkat ke titik yang sebenarnya penting.
grep -cxvFf abc.txt mno.txt
?fgrep
,egrep
alternatif seharusnya sudah usang (mendukunggrep -F
,grep -E
- meskipun saya tidak yakin ada yang percaya mereka akan pernah pergi-x
saat menggunakan-F
?abcdef
haruskah hal itu dianggap sebagai kecocokan atau ketidakcocokanabcd
?Kita bisa menggunakan awk untuk melakukan pekerjaan dengan melewatkan dua file, pertama file pola, lalu file yang ingin kita periksa. Ketika kita membaca file pertama, kita tahu itu
NR==FNR
dan pada saat itu kita dapat membaca baris ke dalam array. KetikaNR!=FNR
kami memeriksa apakah array untuk baris tersebut diatur.Sebaliknya, kita dapat meniadakan pola untuk mencetak garis yang tidak ada
abc.txt
Dan jika kita ingin mencetak hitungan yang bisa kita pakai
sort
danwc
:sumber
abc.txt
-mno.txt
yang{xyz, pqrs}
.Jika salah satu dari daftar kata tidak disortir, akan lebih cepat untuk menggunakan struktur data yang efisien untuk mengingat kata-kata umum.
Python
Pemakaian:
Python (lebih efisien)
Jika Anda ingin menghemat sedikit memori untuk penyimpanan perantara dan menjalankan waktu, Anda dapat menggunakan program yang sedikit lebih sulit dimengerti ini:
Performa
Diberikan
abc.txt
danmno.txt
dengan 1 mio baris tidak disortir masing-masing 10 karakter ASCII acak (lihat jawaban Oli untuk pengaturannya):vs.
total: 23 detik
sumber