Bagaimana menghapus garis duplikat dengan awk sambil menjaga garis kosong?


13

awkPerintah di bawah ini menghapus semua baris duplikat seperti yang dijelaskan di sini :

awk '!seen[$0]++'

Jika teks berisi baris kosong, semua kecuali satu baris kosong akan dihapus.

Bagaimana saya bisa menjaga semua baris kosong sementara menghapus semua baris duplikat yang tidak kosong, hanya menggunakan awk? Tolong, sertakan juga penjelasan singkat.

Jawaban:


28

Pilihan lain adalah memeriksa NF, misalnya:

awk '!NF || !seen[$0]++'

11

kalau tidak

awk '!/./ || !seen[$0]++' file

Trik utamanya adalah sama, seen[$0]++membuat entri dalam seenarray asosiatif yang kuncinya adalah baris saat ini ( $0). Karena itu, !seen[$0]++akan salah jika baris ini sudah terlihat. Ini /./memeriksa apakah baris berisi karakter yang tidak kosong, jadi !/./cocok dengan baris yang tidak kosong. Digabungkan dengan || !seen[$0]++itu akan mengabaikan semua baris duplikat kecuali yang kosong dan mencetak sisanya.


Saya pikir ini seharusnya jawaban yang diterima. +1 untuk penjelasan!
SS Anne

5
awk '/^[[:blank:]]*$/ { print; next; }; !seen[$0]++'

Yang harus Anda lakukan adalah memeriksa baris kosong (benar-benar kosong atau hanya kosong) terlebih dahulu.


5

Berikut adalah awksolusi lain , mirip dengan jawaban @ Thor, kurang ringkas tetapi lebih efisien:

awk '!NF {print;next}; !($0 in a) {a[$0];print}' file

Dengan ini, kami hanya memeriksa apakah a[$0]sudah ada atau belum. Jika tidak, inisialisasi maka cetak. Dalam hal ini, kami tidak memiliki referensi, penugasan a[$0]apakah ada.


Saya tidak mengukur perbedaan waktu yang signifikan dengan file tes 288-line saya. Namun, kode Anda tentu saja menangkap hadiah sebagai yang paling mudah dibaca.
Serge Stroobandt
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.