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.


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).


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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.