Hapus baris duplikat dari file teks yang sangat besar [duplikat]

3

Pertanyaan ini sudah ada jawabannya di sini:

Saya memiliki file teks yang sangat besar (> 50 GB), tetapi sebagian besar baris adalah duplikat, jadi saya ingin menghapusnya. Apakah ada cara untuk menghapus garis duplikat dari file, dan menangani file> 2GB? Karena setiap metode yang saya temukan sampai sekarang hanya dapat berfungsi pada file kecil.

Muis
sumber
Lebih baik tulis skrip Python, yang bisa melakukannya. OS apa? Python dapat melakukan apa saja.
RProgram
Harap selalu sertakan OS Anda. Solusi sangat sering bergantung pada Sistem Operasi yang digunakan. Apakah Anda menggunakan Windows, Linux, Unix, OSX, BSD? Versi yang mana?
terdon
Apakah Anda mencoba mengurutkan -u pada file besar? Mungkin berhasil, Anda tahu ... jika tidak, Anda juga dapat menambalnya alih-alih memulai program C dari awal.
user2987828
Apakah garis duplikat berurutan? Jika demikian, uniqadalah teman Anda, karena itu tidak perlu. Jika duplikat sebagian besar berturut-turut, Anda masih dapat menggunakan uniquntuk memproses ulang file untuk disortir.
David Foerster
@terdon Saya sedang mencari solusi Windows, saya seharusnya menyebutkan itu.
Muis

Jawaban:

4

Dengan asumsi semua baris lebih pendek dari 7kB, dan bahwa Anda memiliki bash, dd, tail, head, sed, dan sortir yang diinstal dari cygwin / unix:

{
  i=0
  while LANG= dd 2>/dev/null bs=1024 skip=${i}000 if=large_text_file count=1021 \
  | LANG= sed -e '1d' -e '$d'  | LANG= sort -u ;
  do
    i=$((1+$i))
  done
  LANG= dd 2>/dev/null bs=1024 skip=${i}000 if=large_text_file count=1021 \
  | LANG= tail -n 1
  LANG= head -n 1 large_text_file
} | LANG= sort -u > your_result

Ini membagi file dalam potongan 1024000 byte, dan menambahkan juga 3 * 7 * 1024 byte ("21" in 1021) dari potongan berikutnya. Karena divisi dapat memotong satu baris, baris pertama ( 1d) dan terakhir ( $d) dari masing-masing bilah dihancurkan ( sed).

Jadi sebagai kompensasi, sesuatu yang mengandung potongan terakhir diekstraksi lagi dan hanya baris terakhirnya yang disimpan (ekor -n 1), dan baris pertama juga diekstraksi lagi (kepala -n 1).

Ketika loop gagal, potongan terakhir telah diekstraksi.

sort -udapat dilihat sebagai kompresor, tetapi hanya memilah inputnya kemudian melewati duplikat. "Sortir" pertama mengkompres semua potongan. Yang kedua sortkompres lagi concatenations semua potongan ini (dan yang kedua sorttelah hilang dari kode di atas sejak edit ketiga, maaf).

Anda mengatakan file teks, tapi saya asumsikan biner, karena itu LANG=(jadi lebih cepat juga).

pengguna2987828
sumber
Apakah ini seharusnya dijalankan pada shell? Shell yang mana? for i=`seq 50000`tidak akan bekerja pada shell * nix apa pun yang saya tahu, maksud Anda for i in $(seq 50000)? Bisakah Anda juga menambahkan beberapa penjelasan tentang apa yang Anda lakukan? Anda menggunakan beberapa trik bagus di sini, tetapi jangan memberi tahu OP apa itu atau bagaimana cara kerjanya.
terdon
Hanya membuat ini di GNU bash, versi 4.2.25 (1) -release (x86_64-pc-linux-gnu): for i in /usr/bin/seq 4; lakukan echo $ i; selesai
user2987828
Ya, itu akan berhasil, tetapi bukan itu yang Anda poskan. for i=`seq 4`tidak setara dengan for i in `seq 4`. Saya telah mengedit jawaban Anda sekarang karena saya tahu ini bukan fitur shell windows yang aneh. Ini benar-benar akan menjadi jawaban yang bagus jika Anda ingin menambahkan penjelasan tentang apa yang dilakukannya. Trik Anda membaca file dalam blok untuk menghilangkan beberapa dupes sebelum menyortir untuk menyingkirkan sisanya adalah ide bagus tetapi sangat sulit untuk dipahami jika Anda tidak fasih dengan alat yang Anda gunakan.
terdon
Ini hanya akan menghapus dupes yang berakhir di chunk yang sama.
Loren Pechtel
Saya baru saja meletakkan kembali yang kedua sortdan didokumentasikan pada akhir posting saya, yang menghapus dupes dari potongan yang berbeda. Ini adalah kesalahan dari hasil edit saya sebelumnya, maaf: itu hanya menghapus dupes yang berakhir pada potongan yang sama, seperti yang ditunjukkan oleh Loren Pechtel.
user2987828
0

Jalankan instance linux di AWS / GCE, dan gunakan 'uniq'. OSX memilikinya juga ...

Documents di sini: http://www.thegeekstuff.com/2013/05/uniq-command-examples/

Clustermagnet
sumber
/ bin / uniq hanya menekan duplikat baris yang sudah bersama. Anda sebaiknya memilih sortir -u jika sesuai dengan memori.
user2987828