Text Processing: awk & sed — Terminal

Text Processing: awk & sed Dua tool klasik Unix ini adalah senjata ampuh untuk memproses teks di terminal — tanpa perlu membuka editor. sed — Stream Editor…

awk dan sed adalah dua alat klasik untuk mengolah teks baris per baris, langsung dari terminal, tanpa membuka editor. Bayangin setumpuk struk belanja. awk itu seperti menyalin satu kolom dari tiap struk, misalnya totalnya saja. sed itu seperti "cari dan ganti" di editor, tapi dijalankan ke setiap baris sekaligus.

🧪 Tebakan cepat: baris 2024-01-15 ERROR user.service Connection failed dikirim ke sed 's/-/./'. Hasilnya 2024.01.15 atau 2024.01-15? Tebak dulu, jawabannya ada di bagian "sed: cari dan ganti".

File contoh: app.log

Semua contoh di pelajaran ini memakai app.log, log sebuah server yang isinya 4 baris:

2024-01-15 ERROR user.service Connection failed
2024-01-15 INFO auth.service Login success
2024-01-16 ERROR db.service Timeout
2024-01-16 WARN cache.service Memory high

awk: ambil kolom

awk membaca file baris demi baris, lalu memecah tiap baris di spasi jadi beberapa field (kolom). Field pertama $1, kedua $2, dan seterusnya. $0 adalah seluruh baris. Baris pertama terpecah begini:

$1 $2 $3 $4 $5
2024-01-15 ERROR user.service Connection failed
$ awk '{print $2}' app.log
ERROR
INFO
ERROR
WARN

Mau baris tertentu saja? Tulis pola di depan kurung kurawal:

$ awk '/ERROR/ {print $3}' app.log
user.service
db.service

/ERROR/ artinya "cuma baris yang memuat ERROR". Hasilnya sama dengan grep ERROR app.log | awk '{print $3}': saring dulu, baru ambil kolom.

Untuk file yang kolomnya dipisah koma (CSV), ganti pemisahnya dengan -F:

$ echo "Alice,30,Jakarta" | awk -F',' '{print $2}'
30

sed: cari dan ganti

sed (stream editor) menjalankan perintah ke setiap baris. Yang paling sering dipakai s, substitute: s/cari/ganti/.

$ sed 's/-/./' app.log
2024.01-15 ERROR user.service Connection failed
2024.01-15 INFO auth.service Login success
2024.01-16 ERROR db.service Timeout
2024.01-16 WARN cache.service Memory high
$ sed 's/-/./g' app.log
2024.01.15 ERROR user.service Connection failed
2024.01.15 INFO auth.service Login success
2024.01.16 ERROR db.service Timeout
2024.01.16 WARN cache.service Memory high

Tanpa g, sed cuma mengganti kemunculan pertama di tiap baris, jadi tanggalnya jadi 2024.01-15. Flag g (global) mengganti semuanya. Itu jawaban tebakannya.

Perintah sed lain yang sering dipakai:

sed 's/2024-01-15/REDACTED/' app.log   # ganti tanggal itu dengan REDACTED
sed '/INFO/d' app.log                  # hapus baris yang memuat INFO
sed -n '2,3p' app.log                  # cetak baris 2 sampai 3 saja

Gabung dengan pipe: sort dan uniq

$ awk '{print $2}' app.log | sort | uniq -c
      2 ERROR
      1 INFO
      1 WARN

Dari terminal ke JavaScript

Latihannya menulis ulang cara kerja ini di JavaScript, dengan 4 baris log yang sama:

Di terminal Di JavaScript, untuk tiap baris line
awk '{print $2}' line.split(" ")[1] (index mulai dari 0, kolom awk mulai dari 1)
grep ERROR lalu awk '{print $3}' filter dengan line.includes("ERROR") dulu, baru ambil kolom
sed 's/2024-01-15/REDACTED/g' line.split("2024-01-15").join("REDACTED")

split(teks).join(pengganti) mengganti semua kemunculan, persis seperti flag g.

⚠️ Jebakan yang sering ketemu

TL;DR: awk memecah tiap baris jadi field: $1, $2, ..., $0 seluruh baris. awk '{print $2}' app.log mengambil kolom ke-2, awk '/ERROR/ {print $3}' cuma dari baris yang memuat ERROR, dan -F',' mengganti pemisahnya untuk CSV. Field yang gak ada jadi kosong. sed 's/cari/ganti/' mengganti kemunculan pertama di tiap baris, tambah g untuk semuanya. sed '/INFO/d' menghapus baris, dan sed baru mengubah file kalau diberi -i. sort | uniq -c menghitung baris kembar, karena uniq cuma membuang yang bersebelahan. Selalu bungkus program awk dan sed dengan tanda kutip satu.

Yang akan kamu pelajari