One-liner ini menghapus baris duplikat dari input teks tanpa penyortiran sebelumnya.
Misalnya:
$ cat >f
q
w
e
w
r
$ awk '!a[$0]++' <f
q
w
e
r
$
Kode asli yang saya temukan di internet berbunyi:
awk '!_[$0]++'
Ini bahkan lebih membingungkan saya ketika saya mengambil _
memiliki arti khusus di awk, seperti di Perl, tapi ternyata hanya nama array.
Sekarang, saya memahami logika di balik satu baris:
setiap baris input digunakan sebagai kunci dalam array hash, jadi, setelah selesai, hash berisi baris unik dalam urutan kedatangan.
Yang ingin saya pelajari adalah bagaimana tepatnya notasi ini diinterpretasikan oleh awk. Misalnya. apa tanda bang (!
) berarti dan elemen lain dari cuplikan kode ini.
Bagaimana cara kerjanya?
Jawaban yang Diterima:
Berikut adalah jawaban "intuitif", untuk penjelasan yang lebih mendalam tentang mekanisme awk, lihat salah satu dari @Cuonglm
Dalam hal ini, !a[$0]++
, ++
post setelah kenaikan dapat disisihkan sejenak, tidak mengubah nilai ekspresi. Jadi, lihat saja !a[$0]
. Di sini:
a[$0]
menggunakan baris saat ini $0
sebagai kunci larik a
, mengambil nilai yang disimpan di sana. Jika kunci khusus ini tidak pernah dirujuk sebelumnya, a[$0]
mengevaluasi ke string kosong.
!a[$0]
!
meniadakan nilai dari sebelumnya. Jika itu kosong atau nol (salah), kami sekarang memiliki hasil yang benar. Jika bukan nol (benar), kami memiliki hasil yang salah. Jika seluruh ekspresi bernilai true, artinya a[$0]
tidak disetel untuk memulai, seluruh baris dicetak sebagai tindakan default.
Selain itu, terlepas dari nilai lama, operator pasca kenaikan menambahkan satu ke a[$0]
, jadi saat berikutnya nilai yang sama dalam array diakses, itu akan menjadi positif dan seluruh kondisi akan gagal.