sed mengubah teks di dalam baris; awk memahami baris itu sebagai data bertkolom. Perintah awk adalah bahasa pemrograman kecil untuk pengolahan teks — namanya diambil dari tiga penciptanya: Aho, Weinberger, dan Kernighan. Kekuatannya ada pada tiga hal: setiap baris otomatis terpecah menjadi field (kolom), blok BEGIN/END memungkinkan laporan berformat, dan array asosiatif menghitung agregasi seperti frekuensi. Pada chapter ini kita memakai file penjualan berformat nama:kategori:jumlah untuk berlatih keempat hal itu.

Struktur Program: pattern { action } #

Program awk tersusun dari pasangan pattern dan action: action dijalankan hanya untuk baris yang cocok dengan pattern. Tanpa pattern, action berlaku untuk semua baris; dan tanpa action ({...}), awk mencetak barisnya. Opsi -F menentukan pemisah field:

bash
printf 'budi:elektronik:1200000\nsiti:elektronik:850000\nandi:sembako:150000\nrini:sembako:200000\njoko:fashion:600000\n' > penjualan.txt
awk -F: '{print $1, $3}' penjualan.txt
awk -F: '{print NR, NF, $0}' penjualan.txt

Output yang Dihasilkan:

text
budi 1200000
siti 850000
andi 150000
rini 200000
joko 600000
1 3 budi:elektronik:1200000
2 3 siti:elektronik:850000
3 3 andi:sembako:150000
4 3 rini:sembako:200000
5 3 joko:fashion:600000

Mari kita bedah baris per barisnya:

  1. Baris 1 (printf ... > penjualan.txt): membuat fixture lima baris berformat nama:kategori:jumlah.
  2. Baris 2 (awk -F: '{print $1, $3}'): opsi -F: memecah setiap baris pada tanda :; $1 adalah nama dan $3 adalah jumlah, sedangkan $0 adalah baris utuh. Koma di antara keduanya menyisipkan spasi.
  3. Baris 3 (awk -F: '{print NR, NF, $0}'): NR (number of records) adalah nomor baris berjalan dan NF (number of fields) adalah jumlah field pada baris itu — keduanya tiga karena tiap baris memiliki dua tanda :.

Cara lain menentukan pemisah adalah blok BEGIN { FS = ":" } di dalam program; hasilnya sama dengan -F:, hanya ditulis dalam bahasa awk sendiri.

Memfilter Baris dengan Pola Perbandingan #

Pattern tidak harus regex — awk juga menerima perbandingan angka dan string. Inilah bedanya dengan grep: awk bisa membandingkan isi kolom, bukan sekadar mencocokkan teks di seluruh baris:

bash
printf 'budi:elektronik:1200000\nsiti:elektronik:850000\nandi:sembako:150000\nrini:sembako:200000\njoko:fashion:600000\n' > penjualan.txt
awk -F: '$3 > 500000 {print $1, $3}' penjualan.txt
awk -F: '$2 == "sembako" {print $1}' penjualan.txt
awk -F: '/budi/ {print}' penjualan.txt

Output yang Dihasilkan:

text
budi 1200000
siti 850000
joko 600000
andi
rini
budi:elektronik:1200000

Perintah pertama membandingkan kolom jumlah: baris dengan $3 di atas 500000 lolos — penyaringan berbasis isi kolom yang tidak bisa dilakukan grep , sebab grep hanya mencocokkan pola pada baris utuh. Perintah kedua menguji kesamaan string: hanya penjual kategori sembako dicetak namanya. Perintah ketiga memakai pola regex /budi/ — kebetulan fungsi yang sama dengan grep budi, tetapi di sini kita bebas menggabungkannya dengan action apa pun.

Blok BEGIN dan END untuk Laporan #

Blok BEGIN berjalan sekali sebelum baris pertama dibaca — cocok untuk mencetak judul tabel. Blok END berjalan sekali setelah baris terakhir — tempat menampilkan hasil penjumlahan. Keduanya dipadukan dengan printf untuk mengatur kolom:

bash
printf 'budi:elektronik:1200000\nsiti:elektronik:850000\nandi:sembako:150000\nrini:sembako:200000\njoko:fashion:600000\n' > penjualan.txt
awk -F: 'BEGIN { printf "%-8s %12s\n", "Nama", "Penjualan" } $3 >= 600000 { printf "%-8s %12d\n", $1, $3 }' penjualan.txt
awk -F: '{ total += $3 } END { printf "Total: %d\n", total }' penjualan.txt

Output yang Dihasilkan:

text
Nama        Penjualan
budi          1200000
siti           850000
joko           600000
Total: 3000000

Program pertama mencetak judul lewat BEGIN, menyaring baris dengan $3 >= 600000, lalu memformatnya: %-8s merata-kiri teks selebar 8 karakter dan %12d merata-kanan angka selebar 12. Program kedua menjumlahkan: setiap baris menambah kolom $3 ke variabel total, dan END mencetak hasil akhirnya — semua penjualan tercatat 3.000.000. Pola variabel += kolom ini adalah cara baku awk menghitung total.

Array Asosiatif untuk Frekuensi #

Array awk diindeks oleh string, bukan angka — disebut array asosiatif. Kombinasi dengan operator ++ menghasilkan penghitung frekuensi yang ringkas: setiap kali sebuah kunci muncul, nilainya bertambah satu:

bash
printf 'budi:elektronik:1200000\nsiti:elektronik:850000\nandi:sembako:150000\nrini:sembako:200000\njoko:fashion:600000\n' > penjualan.txt
awk -F: '{ hitung[$2]++ } END { for (k in hitung) print k, hitung[k] }' penjualan.txt | sort
awk -F: '{ subtotal[$2] += $3 } END { for (k in subtotal) print k, subtotal[k] }' penjualan.txt | sort

Output yang Dihasilkan:

text
elektronik 2
fashion 1
sembako 2
elektronik 2050000
fashion 600000
sembako 350000

Mari kita bedah baris per barisnya:

  1. Baris 1: membuat ulang fixture agar blok ini bisa dijalankan sendiri.
  2. Baris 2 ({ hitung[$2]++ }): untuk tiap baris, kunci array adalah kategori ($2); setiap penjualan menambah hitungan kategorinya satu. Blok END lalu menelusuri array dengan for (k in hitung) dan mencetak pasangan kunci–nilai. Pipe ke sort menjaga urutan hasil tetap stabil karena awk tidak menjamin urutan penelusuran array.
  3. Baris 3 ({ subtotal[$2] += $3 }): resep yang sama, tetapi yang dijumlahkan adalah nilai penjualan — menghasilkan subtotal per kategori.

Dengan tiga bahan ini — field, filter, agregasi — awk sanggup menjadi mesin laporan satu baris. Hasil laporan sering kali perlu diurutkan dan diringkas lebih jauh; di situlah trio sort, uniq, dan cut berperan, materi chapter berikutnya. Spesifikasi lengkap bahasa awk tercantum di standar POSIX .