Bab 9.1.3 sudah menyinggung sekilas bahwa awk unggul saat data yang diolah punya struktur kolom, berbeda dari grep yang cuma mencari baris dan sed di Bab 10 yang mengubah teks per baris sebagai stream. Kelebihan itu membuat awk jadi pilihan utama begitu sebuah baris teks perlu dipecah jadi beberapa bagian bermakna, misalnya output df -h yang punya kolom ukuran disk, atau file CSV hasil ekspor laporan penjualan yang tiap barisnya berisi tanggal, produk, dan harga. Sysadmin memakai awk nyaris setiap hari untuk merangkum log dan output perintah sistem jadi laporan singkat, sementara Developer memakainya untuk mengekstrak kolom tertentu dari output build atau file data terstruktur di dalam pipeline. Bab ini membahas tuntas awk: konsep pattern-action yang jadi fondasi setiap program awk, cara mengakses kolom lewat $1, $2, dan variabel bawaan seperti NF/NR, kondisi-loop-fungsi di dalam bahasa awk itu sendiri, hingga studi kasus nyata membuat laporan dan rekap dari file CSV dan log. Regex ERE yang sudah dibahas di Bab 9.3.3 akan terus terpakai di sepanjang bab ini, jadi pastikan konsepnya masih segar sebelum lanjut.
11.1 Konsep dan Struktur Program awk
Sub-bab ini membahas apa itu awk secara singkat dan bagaimana struktur dasar sebuah program awk disusun, secukupnya sebagai bekal sebelum masuk ke praktik field processing di 11.2.
11.1.1 Apa itu awk
awk bukan sekadar perintah tunggal seperti grep atau sed, melainkan sebuah bahasa pemrograman tersendiri yang dirancang khusus untuk mengolah data berbasis teks, terutama data yang punya struktur berulang seperti kolom dan baris. Namanya sendiri adalah singkatan dari nama belakang tiga penciptanya, Alfred Aho, Peter Weinberger, dan Brian Kernighan, yang mengembangkannya di Bell Labs sekitar tahun 1977, era yang sama dengan lahirnya sed yang sudah dibahas di Bab 10.1.1. Perbedaan paling mendasar dengan sed: sed memproses teks sebagai satu kesatuan baris utuh, sedangkan awk otomatis memecah setiap baris menjadi kolom-kolom kecil begitu dibaca, sehingga kita bisa langsung merujuk kolom kedua atau ketiga tanpa perlu menulis regex ekstraksi manual.
Ada beberapa implementasi awk yang beredar, dan perilakunya bisa sedikit berbeda satu sama lain, mirip kasus GNU sed vs BSD sed di Bab 10.1.3. GNU Awk (disingkat gawk) adalah implementasi paling lengkap fiturnya dan paling umum ditemui di distro Linux. mawk, implementasi yang lebih ringan dan cepat, sering jadi awk default di beberapa distro turunan Debian seperti Ubuntu. Sementara itu, macOS membawa implementasi asli dari penciptanya sendiri, dikenal sebagai the one true awk atau BWK awk (inisial Brian W. Kernighan), sebagai awk bawaan sistem. Ketiganya sama-sama mengikuti spesifikasi POSIX Awk untuk fitur intinya, jadi contoh-contoh dasar di bab ini tetap berjalan konsisten di semua varian, tapi beberapa fitur lanjutan yang bersifat ekstensi gawk akan ditandai secara eksplisit supaya kita tahu batasan portabilitasnya, dibahas lebih dalam di 11.4.4.
11.1.2 Anatomi Pattern dan Action
Setiap program awk tersusun dari satu atau lebih pasangan pattern (pola) dan action (aksi), ditulis dengan bentuk umum berikut.
awk 'pattern { action }' file.txtawk membaca input baris demi baris, dan tiap baris yang dibaca disebut satu record (rekaman). Untuk setiap record, awk menguji apakah pattern cocok. Kalau cocok, blok action di dalam kurung kurawal dijalankan. Baik pattern maupun action sebenarnya opsional, tapi salah satunya wajib ada. Kalau pattern dikosongkan, action berjalan untuk setiap baris tanpa terkecuali.
awk '{print}' catatan.txtPerintah di atas menampilkan seluruh isi catatan.txt apa adanya, karena tanpa pattern, action {print} berjalan di setiap baris, mirip fungsi cat yang sudah dibahas di Bab 2.3. Sebaliknya, kalau action dikosongkan, awk memakai aksi default berupa print $0, yaitu mencetak seluruh baris yang cocok apa adanya, mirip cara kerja grep di Bab 9.2.
awk '/error/' /var/log/aplikasi.logPerintah di atas menampilkan setiap baris di aplikasi.log yang mengandung teks error, karena /error/ adalah bentuk pattern berupa regex yang otomatis dicocokkan terhadap seluruh isi baris ($0). Dialek regex yang dipakai awk pada dasarnya adalah ERE (Extended Regular Expression), dialek yang sama seperti grep -E atau sed -E yang sudah dibahas di Bab 9.3.3 dan 10.4.3, jadi metakarakter seperti +, ?, |, dan ( ) langsung dikenali tanpa perlu di-escape.
Selain pattern berupa regex, awk juga mengenal dua pattern khusus, BEGIN dan END, yang tidak terikat pada baris input mana pun. Blok BEGIN dijalankan tepat satu kali sebelum baris pertama dibaca, sedangkan blok END dijalankan tepat satu kali setelah seluruh baris input selesai diproses. Kombinasi ini sangat berguna untuk inisialisasi di awal dan pencetakan hasil rekap di akhir, pola yang akan sering dipakai di studi kasus 11.4.
awk 'BEGIN {print "Mulai memproses..."} /error/ {jumlah++} END {print "Total baris error:", jumlah}' /var/log/aplikasi.logProgram di atas menggabungkan tiga pattern sekaligus dalam satu perintah: BEGIN mencetak pesan pembuka, pattern /error/ menambah variabel jumlah setiap kali baris mengandung error ditemukan, dan END mencetak total di akhir. Satu hal yang membedakan awk dari Bash: variabel di dalam awk tidak perlu dideklarasikan lebih dulu dan otomatis dianggap bernilai 0 atau string kosong saat pertama dipakai, sehingga jumlah++ langsung berjalan tanpa perlu inisialisasi jumlah=0 di blok BEGIN.
11.1.3 Memeriksa Versi awk Terpasang
Sebelum praktik lebih jauh, ada baiknya kita cek dulu varian awk yang terpasang di sistem, karena seperti disinggung di 11.1.1, ketersediaan fitur lanjutan bisa berbeda antar implementasi.
awk --versionKalau yang terpasang adalah gawk, perintah di atas menampilkan baris berisi GNU Awk beserta nomor versinya. Perlu dicatat, opsi --version ini bukan bagian resmi spesifikasi POSIX Awk, sehingga tidak dijamin dikenali oleh setiap implementasi. mawk yang jadi default awk di banyak distro Debian-based seperti Ubuntu kebetulan tetap mengenali opsi ini (diturunkan dari opsi internalnya sendiri, -W version) dan tetap menampilkan versi beserta info hak ciptanya, meski formatnya berbeda dari gawk. Bedanya baru terasa di BWK awk bawaan macOS yang disinggung di 11.1.1: implementasi ini tidak mengenali opsi panjang gaya GNU sama sekali, sehingga --version diperlakukan sebagai opsi tak dikenal yang diabaikan, dan perintah biasanya berakhir dengan keluhan tidak ada program yang diberikan, bukan menampilkan nomor versi. Kalau perintah di atas menghasilkan pesan yang tidak jelas seperti itu, cara paling aman memastikan implementasi mana yang benar-benar terpasang adalah menelusuri lokasi binary-nya.
command -v awk
readlink -f "$(command -v awk)"User dan Sysadmin yang bekerja di macOS dan ingin fitur lengkap gawk yang konsisten dengan Linux bisa memasangnya lewat Homebrew (topik instalasi Homebrew sudah disinggung di Bab 1.3). Berbeda dari GNU sed yang terpasang sebagai gsed di Homebrew untuk menghindari bentrok nama seperti dibahas di Bab 10.1.3, paket gawk terpasang langsung dengan nama perintah gawk, karena memang tidak ada program bernama gawk bawaan macOS yang bisa bentrok.
brew install gawk
gawk --version11.2 Field Processing dan Variabel Bawaan
Sub-bab ini membahas cara awk memecah setiap baris menjadi kolom-kolom kecil yang disebut field, beserta variabel-variabel bawaan yang paling sering dipakai untuk mengakses dan menghitung field itu.
| Variabel | Arti |
|---|---|
$0 | Seluruh isi record (baris) saat ini, apa adanya |
$1, $2, ... | Isi field pertama, kedua, dan seterusnya pada record saat ini |
NF | Jumlah field pada record saat ini (Number of Fields) |
NR | Nomor urut record yang sudah dibaca, dihitung dari seluruh input (Number of Records) |
FNR | Nomor urut record, tapi dihitung ulang dari 1 di setiap file baru (File Number of Records) |
FS | Field Separator, karakter/pola pemisah antar field pada input |
OFS | Output Field Separator, pemisah antar field saat awk mencetak ulang $0 |
11.2.1 Field dan Record: $0 hingga NF
Secara default, awk memecah setiap baris menjadi field berdasarkan spasi dan tab, sehingga kita bisa langsung merujuk kolom tertentu tanpa perlu menghitung posisi karakter secara manual seperti pada ${var:offset:length} di Bab 9.4.2.
df -h | awk '{print $1, $NF}'Perintah di atas menampilkan kolom pertama (Filesystem) dan kolom terakhir (titik mount) dari output df -h, tool yang sudah disinggung sekilas di Bab 17. Notasi $NF ini adalah trik yang sangat berguna, karena NF selalu berisi jumlah field pada record yang sedang diproses, sehingga $NF otomatis merujuk field terakhir apa pun isinya, tanpa perlu tahu persis ada berapa kolom di baris itu. Satu jebakan yang perlu diwaspadai di lapangan: nilai NF bisa berbeda antar baris pada file yang sama. Baris header df -h biasanya mengandung frasa dua kata "Mounted on", sehingga header itu punya satu field lebih banyak dibanding baris data yang cuma berisi satu path tanpa spasi. Kalau kolom yang diproses berpotensi mengandung spasi, jangan asumsikan NF selalu sama di setiap baris.
11.2.2 Penghitung Baris: NR dan FNR
NR bertambah satu setiap kali awk membaca satu record baru, terus berlanjut lintas file kalau lebih dari satu file diberikan sebagai input. FNR punya perilaku mirip, tapi ia direset kembali ke 1 setiap kali awk mulai membaca file baru.
awk '{print FNR, NR, $0}' aplikasi-1.log aplikasi-2.logKalau aplikasi-1.log punya 5 baris, baris pertama aplikasi-2.log akan menampilkan FNR bernilai 1 (karena file baru dimulai), tapi NR bernilai 6 (karena penghitungan lanjut dari file sebelumnya). Perbedaan ini penting dipahami saat memproses banyak file berurutan dan kita perlu tahu persis apakah sedang berada di file yang mana. Pemakaian NR paling umum di lapangan adalah melewati baris header pada file CSV, karena baris pertama biasanya berisi nama kolom, bukan data sungguhan.
awk 'NR > 1 {print}' data.csvPerintah di atas menampilkan seluruh baris data.csv kecuali baris pertama. Pola NR > 1 di sini bertindak sebagai pattern berupa ekspresi perbandingan, salah satu bentuk pattern yang belum dibahas eksplisit di 11.1.2, dan akan diperdalam di 11.3.1.
11.2.3 Field Separator: FS, -F, dan OFS
Field separator default awk punya perilaku khusus: kalau FS bernilai satu karakter spasi (nilai bawaannya), awk memperlakukan setiap rangkaian spasi dan tab berturut-turut sebagai satu pemisah tunggal, sekaligus mengabaikan spasi di awal dan akhir baris. Perilaku inilah yang membuat contoh df -h di 11.2.1 tetap rapi meski lebar kolom aslinya tidak seragam.
Untuk file yang dipisah karakter lain, seperti file CSV yang dipisah koma atau /etc/passwd yang dipisah titik dua, kita perlu mengatur FS secara eksplisit lewat opsi -F di baris perintah.
awk -F: '{print $1}' /etc/passwdPerintah di atas menampilkan daftar nama akun yang terdaftar di sistem, karena field pertama pada setiap baris /etc/passwd memang nama akun, dipisah titik dua dari field lainnya seperti UID dan home directory. Untuk file CSV, pola yang sama berlaku dengan FS berupa koma.
awk -F',' '{print $2}' penjualan.csvFS juga bisa diisi lebih dari satu karakter, dan begitu itu terjadi, awk memperlakukannya sebagai regex ERE, bukan lagi karakter literal tunggal, berguna saat sebuah file dipisah oleh lebih dari satu jenis delimiter sekaligus.
awk -F'[,;]' '{print $1}' data_campuran.txtPerintah di atas memecah field berdasarkan koma atau titik koma, keduanya dianggap pemisah yang valid berkat character class [,;] yang konsepnya sama seperti dibahas di Bab 9.3.2.
Sementara FS mengatur cara awk membaca input, OFS mengatur karakter pemisah yang dipakai saat awk menyusun ulang $0 untuk dicetak. Satu jebakan yang wajib diketahui: OFS baru benar-benar dipakai kalau $0 disusun ulang, misalnya setelah salah satu field diubah nilainya. Sekadar mencetak $0 tanpa mengubah field apa pun tetap memakai separator asli dari input, bukan OFS.
awk 'BEGIN {FS=","; OFS="|"} {$1=$1; print}' penjualan.csvTrik $1=$1 di atas sengaja menetapkan ulang field pertama dengan nilainya sendiri, tindakan yang terlihat tidak melakukan apa-apa tapi sebenarnya memaksa awk menyusun ulang seluruh $0 memakai OFS yang baru. Hasilnya, file yang tadinya dipisah koma tercetak ulang dengan pemisah |, cara praktis mengonversi format delimiter sebuah file tanpa perlu sed sama sekali.
11.3 Kondisi, Loop, dan Fungsi
Sub-bab ini membahas struktur kendali di dalam bahasa awk sendiri, mulai dari percabangan kondisi, perulangan, sampai fungsi bawaan dan fungsi buatan sendiri, yang semuanya ditulis di dalam blok { action } yang sudah dikenalkan di 11.1.2.
11.3.1 Kondisi if-else dan Operator Perbandingan
Sintaks if/else di awk mirip bahasa pemrograman C, sedikit berbeda dari sintaks if/then/fi Bash yang sudah dibahas di Bab 6.1.
awk -F',' 'NR > 1 {
if ($3 > 10) {
print $2, "terjual banyak"
} else {
print $2, "terjual sedikit"
}
}' penjualan.csvOperator perbandingan yang dipakai juga mengikuti gaya C: ==, !=, <, >, <=, >=, digabung dengan operator logika && (dan), || (atau), dan ! (negasi), persis makna yang sama seperti operator logika Bash di Bab 6.4.2. Untuk pencocokan pola regex secara eksplisit di dalam kondisi, awk menyediakan operator ~ (cocok) dan !~ (tidak cocok).
awk -F',' '$2 ~ /^Kopi/ {print}' penjualan.csvPerintah di atas menampilkan baris yang field keduanya diawali kata Kopi, memakai regex ERE yang sama seperti pattern /error/ di 11.1.2, tapi kali ini diterapkan khusus ke satu field tertentu lewat operator ~, bukan ke seluruh $0.
11.3.2 Loop for dan while
awk mendukung for dan while dengan sintaks yang juga mirip C, berbeda dari sintaks for item in list yang lebih umum dipakai di Bash (Bab 7.1).
awk '{
for (i = 1; i <= NF; i++) {
print "Field", i, "=", $i
}
}' catatan.txtProgram di atas mencetak setiap field pada tiap baris satu per satu, memanfaatkan NF sebagai batas akhir perulangan dan notasi $i untuk mengakses field secara dinamis lewat variabel i, bukan angka tetap seperti $1. Kemampuan mengakses field lewat variabel inilah yang membuat awk jauh lebih fleksibel dibanding memanggil $1, $2, dan seterusnya satu per satu secara manual, terutama saat jumlah kolom sebuah file tidak selalu tetap.
while di awk juga tersedia untuk kasus perulangan berbasis kondisi, dan do-while untuk kasus yang badan loop-nya wajib berjalan minimal sekali sebelum kondisi diperiksa, walau di lapangan for jauh lebih sering dipakai karena kebanyakan perulangan di awk berkutat seputar field atau elemen array yang jumlahnya sudah diketahui.
11.3.3 Fungsi Bawaan dan Fungsi Buatan Sendiri
awk menyediakan sejumlah built-in function (fungsi bawaan) untuk mengolah string dan angka, beberapa di antaranya yang paling sering dipakai dirangkum di tabel berikut.
| Fungsi | Fungsi/Kegunaan |
|---|---|
length(str) | Jumlah karakter pada str; tanpa argumen, mengembalikan panjang $0 |
substr(str, awal, panjang) | Mengekstrak sebagian str mulai posisi awal (dihitung dari 1) |
split(str, arr, fs) | Memecah str ke dalam array arr berdasarkan pemisah fs |
sub(pola, pengganti, target) | Mengganti kemunculan pertama pola di target (default $0) |
gsub(pola, pengganti, target) | Sama seperti sub, tapi mengganti seluruh kemunculan |
index(str, sub) | Posisi kemunculan pertama sub di dalam str, atau 0 jika tidak ditemukan |
toupper(str) / tolower(str) | Mengonversi str jadi huruf besar/kecil seluruhnya |
awk -F',' '{print toupper($2), length($2)}' penjualan.csvPerintah di atas mencetak nama produk dalam huruf kapital beserta jumlah karakternya, gabungan dua fungsi bawaan sekaligus. Fungsi sub dan gsub berperilaku mirip perintah s/// pada sed yang sudah dibahas di Bab 10.2.1, hanya saja ditulis sebagai pemanggilan fungsi, bukan sintaks tersendiri.
echo "kucing kucing kucing" | awk '{gsub(/kucing/, "anjing"); print}'Perintah di atas menghasilkan anjing anjing anjing, karena gsub tanpa argumen target ketiga otomatis bekerja pada $0 dan mengganti seluruh kemunculan, setara dengan sed 's/kucing/anjing/g'.
Selain fungsi bawaan, kita juga bisa menulis user-defined function (fungsi buatan sendiri) memakai kata kunci function, konsepnya sejalan dengan fungsi Bash di Bab 8, tapi dengan sintaks yang berbeda.
function persentase(bagian, total) {
return (bagian / total) * 100
}
BEGIN {
print persentase(25, 200)
}Program di atas mendefinisikan fungsi persentase yang menerima dua parameter dan mengembalikan hasil bagi dalam bentuk persen lewat return, mirip konsep return value yang sudah dibahas di Bab 8.3. Satu idiom khas awk yang layak diketahui: parameter tambahan yang sengaja ditulis di daftar parameter tapi tidak pernah diisi saat pemanggilan fungsi otomatis berperan sebagai variabel lokal, mirip konsep local variable di Bab 8.4, tapi dengan cara deklarasi yang unik ini karena awk tidak punya kata kunci local tersendiri seperti Bash.
function tandai_besar(nilai, hasil) {
if (nilai > 100) {
hasil = "besar"
} else {
hasil = "kecil"
}
return hasil
}Perhatikan spasi ekstra sebelum hasil pada daftar parameter di atas. Spasi ini murni konvensi penulisan yang dianjurkan komunitas awk untuk membedakan secara visual mana parameter yang benar-benar diisi pemanggil (nilai) dan mana yang cuma dipakai sebagai variabel kerja internal (hasil), bukan aturan sintaks yang wajib diikuti oleh interpreter.
11.4 Studi Kasus: Laporan CSV dan Log
Sub-bab penutup ini menggabungkan seluruh teknik dari 11.1 sampai 11.3 untuk membuat laporan dari file CSV, skenario yang sering dihadapi Sysadmin maupun Developer saat perlu merangkum data tanpa membuka aplikasi spreadsheet. Sebagai contoh, anggap kita punya file penjualan.csv berikut.
tanggal,produk,jumlah,harga
2026-08-01,Kopi,10,25000
2026-08-01,Teh,5,15000
2026-08-02,Kopi,8,25000
2026-08-02,Roti,12,12000
2026-08-03,Teh,7,1500011.4.1 Total dan Rata-rata Kolom Numerik
Kebutuhan paling umum saat mengolah data tabular adalah menjumlahkan sebuah kolom numerik, dalam kasus ini menghitung total pendapatan dari seluruh transaksi.
awk -F',' '
NR > 1 {
total += $3 * $4
jumlah_transaksi++
}
END {
printf "Total pendapatan: %d\n", total
printf "Rata-rata per transaksi: %.2f\n", total / jumlah_transaksi
}' penjualan.csvProgram di atas melewati baris header lewat NR > 1 seperti dibahas di 11.2.2, mengalikan jumlah ($3) dengan harga ($4) di setiap baris, lalu mengakumulasikannya ke variabel total. Blok END mencetak hasil akhirnya dengan printf, fungsi cetak yang formatnya sama persis seperti printf pada Bash di Bab 5.1, lengkap dengan format specifier seperti %d untuk angka bulat dan %.2f untuk angka desimal dua digit. Berdasarkan data contoh di atas, hasilnya adalah total pendapatan 774000 dan rata-rata 154800.00 per transaksi.
11.4.2 Rekap per Kategori dengan Associative Array
Kebutuhan berikutnya yang sering muncul adalah merekap data per kategori, misalnya total pendapatan per produk. awk menyediakan associative array, array yang indeksnya berupa string alih-alih angka berurutan, konsepnya sejalan dengan declare -A di Bash yang sudah dibahas di Bab 4.2, tapi di awk array otomatis bersifat asosiatif tanpa perlu deklarasi eksplisit.
awk -F',' '
NR > 1 {
pendapatan[$2] += $3 * $4
}
END {
for (produk in pendapatan) {
printf "%-10s Rp%d\n", produk, pendapatan[produk]
}
}' penjualan.csvProgram di atas memakai nama produk ($2) sebagai indeks array pendapatan, sehingga setiap kali produk yang sama muncul lagi di baris berikutnya, nilainya otomatis terakumulasi ke indeks yang sama. Perulangan for (produk in pendapatan) mengiterasi seluruh indeks yang pernah dipakai, pola perulangan array asosiatif yang belum disinggung di 11.3.2. Untuk data contoh di atas, hasilnya berupa tiga baris rekap: Kopi dengan pendapatan 450000, Teh dengan 180000, dan Roti dengan 144000. Satu catatan penting yang wajib diketahui: urutan hasil for...in pada spesifikasi POSIX Awk memang tidak dijamin urut sesuai kemunculan pertama atau urutan abjad, sehingga urutan baris rekap yang tercetak bisa berbeda-beda tiap kali dijalankan atau berbeda antar implementasi awk. Kalau urutan tampilan penting, hasil awk ini sebaiknya disalurkan lewat pipe ke sort (Bab 5.3) sebagai langkah tambahan.
11.4.3 Studi Kasus Log: Menghitung Kode Status HTTP
Teknik rekap dengan associative array di 11.4.2 tidak cuma berlaku untuk file CSV yang rapi. Sysadmin sehari-hari lebih sering menghadapi file log web server seperti access log Apache atau Nginx, yang formatnya lazim disebut Common Log Format, dengan contoh satu baris berikut.
192.168.1.10 - - [30/Aug/2026:10:15:32 +0700] "GET /index.html HTTP/1.1" 200 512Baris seperti ini tidak dipisah koma seperti CSV, tapi tetap bisa dipecah lewat FS spasi bawaan awk yang sudah dibahas di 11.2.3, meski hasil pemisahannya perlu dicermati lebih dulu. Karena tanggal diapit kurung siku yang isinya mengandung spasi, dan baris permintaan HTTP diapit tanda kutip yang juga mengandung spasi, kedua bagian itu ikut terpecah jadi beberapa field terpisah. Pada format log ini, field kesembilan ($9) hampir selalu berisi kode status HTTP, dan field kesepuluh ($10) berisi ukuran response dalam byte, posisi yang konsisten selama format log tidak dimodifikasi.
awk '{status[$9]++} END {for (kode in status) print kode, status[kode]}' akses.logProgram di atas persis memakai pola yang sama seperti rekap produk di 11.4.2, hanya saja indeks array-nya sekarang kode status HTTP, bukan nama produk. Untuk log yang berisi tiga baris berkode 200, satu baris 404, dan satu baris 500, hasilnya berupa tiga baris rekap berisi masing-masing kode status beserta jumlah kemunculannya. Pola one-liner semacam ini sangat umum dipakai Sysadmin untuk memeriksa cepat kesehatan sebuah layanan, misalnya menghitung berapa banyak request yang berakhir dengan kode 5xx (error server) dalam satu file log, tanpa perlu membuka tool monitoring terpisah. Pembahasan lebih dalam soal membaca dan mengolah log server, termasuk journalctl, menyusul di Bab 19.
11.4.4 Troubleshooting: Portabilitas awk
Seperti disinggung di 11.1.1, tiga implementasi awk yang paling umum ditemui (gawk, mawk, dan BWK awk bawaan macOS) sama-sama mendukung fitur inti sesuai POSIX Awk yang sudah dipakai di seluruh bab ini: pattern-action, field, NF/NR, kondisi, loop, associative array, hingga fungsi bawaan dasar seperti substr dan gsub. Namun, gawk juga menyediakan sejumlah ekstensi khusus di luar POSIX, misalnya fungsi gensub() untuk substitusi dengan backreference, fungsi strftime() untuk format tanggal, atau length(array) untuk menghitung jumlah elemen sebuah array secara langsung. Skrip yang memakai fitur-fitur ini akan gagal dijalankan di mawk atau BWK awk, karena keduanya sama sekali tidak mengenal nama fungsi tersebut, dan proses biasanya berhenti dengan pesan galat yang intinya memberi tahu bahwa fungsi itu tidak terdefinisi.
Kebiasaan yang baik di lapangan untuk Sysadmin yang scriptnya perlu portable ke banyak server dengan implementasi awk berbeda-beda: pegang teguh fitur yang sudah dibahas di bab ini sebagai fondasi utama, karena semuanya sudah sesuai POSIX Awk dan dijamin berjalan konsisten di implementasi mana pun. Kalau memang butuh fitur ekstensi gawk yang lebih canggih, pastikan lebih dulu gawk benar-benar terpasang di server tujuan, dan panggil secara eksplisit lewat perintah gawk, bukan cuma awk, karena seperti dibahas di 11.1.1 dan 11.1.3, perintah awk di sebuah sistem tidak selalu mengarah ke gawk.
Setelah menguasai grep, sed, dan awk sebagai tiga tool inti pemrosesan teks, Bab 12 melanjutkan ke topik yang justru berpusat kembali ke Bash sendiri: cara menangani argumen yang dikirim ke sebuah script, mulai dari positional parameter sederhana sampai parsing opsi lengkap gaya -v/--verbose lewat getopts.

