Konfigurasi, catatan, dan log di Linux semuanya adalah file teks — kemampuan utama skrip shell adalah mengolahnya. Pipe dan redirection dari Section Command Line sudah memperkenalkan alatnya; sekarang kita memakai alat itu di dalam skrip, tempat hasilnya bisa disimpan ke variabel, dijadikan keputusan, atau dicetak sebagai laporan. Chapter ini memakai satu file data latihan untuk membedah cut, sort dengan uniq, grep, dan awk, lalu menutup dengan membaca seluruh file ke variabel serta memecah path dengan basename dan dirname.
Menyiapkan Data dan Memotong Kolom dengan cut #
Kita pakai file karyawan.txt berformat nama:umur:kota sebagai data latihan — format dengan pemisah titik dua seperti ini juga dipakai file sistem sungguhan seperti /etc/passwd. Perintah cut memotong tiap baris menjadi kolom berdasarkan pemisah itu:
printf 'budi:25:Bandung\nsiti:31:Jakarta\nani:22:Bandung\nrato:35:Surabaya\n' > karyawan.txt
cat karyawan.txt
cut -d: -f1,3 karyawan.txtOutput yang Dihasilkan:
budi:25:Bandung
siti:31:Jakarta
ani:22:Bandung
rato:35:Surabaya
budi:Bandung
siti:Jakarta
ani:Bandung
rato:SurabayaOpsi -d: menetapkan titik dua sebagai delimiter pemisah kolom, dan -f1,3 memilih kolom ke-1 serta ke-3 — nama dan kota — sementara kolom umur dibuang. Bentuk rentang -f1-3 juga sah bila kolomnya berurutan. Spesifikasi lengkap opsi -d dan -f dibaca pada halaman manual cut(1)
. Karena tiap blok latihan pada chapter ini bersifat mandiri, baris printf pembuat karyawan.txt akan kita tulis ulang di awal tiap blok — salinan > selalu menimpa, jadi hasilnya sama bagi pembaca yang melanjutkan dari blok sebelumnya.
Mengurutkan dan Meringkas dengan sort, uniq, dan grep #
Pertanyaan nyata pada data seperti ini biasanya berbunyi “berapa kali tiap kota muncul?” — dan jawabannya adalah pipeline klasik tiga tahap yang sudah kita kenal, kini diarahkan dari kolom pilihan cut:
printf 'budi:25:Bandung\nsiti:31:Jakarta\nani:22:Bandung\nrato:35:Surabaya\n' > karyawan.txt
cut -d: -f3 karyawan.txt | sort | uniq -c | sort -rn
grep -c Bandung karyawan.txtOutput yang Dihasilkan:
2 Bandung
1 Surabaya
1 Jakarta
2Pipeline pertama bekerja bertahap: cut mengambil kolom kota saja, sort mengelompokkan kota sama bersebelahan, uniq -c meringkas tiap kelompok menjadi satu baris berisi jumlahnya, dan sort -rn mengurutkan hasil menurut angka secara menurun — Bandung dengan dua karyawan naik ke puncak. Baris kedua memakai grep -c yang menghitung baris yang cocok: 2 karena dua baris memuat Bandung. Beda keduanya: pipeline menghitung tiap nilai, grep -c menghitung kemunculan satu nilai yang kita tentukan.
Memfilter dan Menghitung dengan awk #
Saat syaratnya menyangkut isi kolom — misalnya “siapa yang berumur 25 ke atas?” — awk lebih tepat karena ia mengenal kolom sebagai $1, $2, dan seterusnya, lengkap dengan kemampuan aritmetika dan printf:
printf 'budi:25:Bandung\nsiti:31:Jakarta\nani:22:Bandung\nrato:35:Surabaya\n' > karyawan.txt
awk -F: '$2 >= 25 {printf "%-6s umur %s\n", $1, $2}' karyawan.txt
awk -F: '{total += $2} END {printf "rata-rata umur: %.1f\n", total/NR}' karyawan.txtOutput yang Dihasilkan:
budi umur 25
siti umur 31
rato umur 35
rata-rata umur: 28.2Perintah pertama memakai pola aksi '$2 >= 25 { ... }': aksi di dalam kurung kurawal hanya dijalankan untuk baris yang lolos syarat, yaitu baris dengan umur minimal 25. Format %-6s mencetak nama rata kiri dalam lebar enam karakter sehingga kolomnya lurus, dan NR adalah nomor baris. Perintah kedua menjumlahkan $2 dari semua baris ke variabel total, lalu blok END — yang berjalan setelah semua baris habis dibaca — membaginya dengan NR untuk mencetak rata-rata 28.2.
Membaca File dan Memecah Path dalam Skrip #
Dalam skrip, output perintah sering perlu ditampung dulu sebelum dipakai. Command substitution $( ) menjaring stdout ke variabel; basename dan dirname memecah sebuah path menjadi nama file dan foldernya:
printf 'budi:25:Bandung\nsiti:31:Jakarta\nani:22:Bandung\nrato:35:Surabaya\n' > karyawan.txt
cat > ringkas.sh <<'AKHIR'
#!/bin/bash
berkas="data/karyawan.txt"
nama=$(basename "$berkas")
folder=$(dirname "$berkas")
isi=$(cat "$berkas")
echo "nama file : $nama"
echo "folder : $folder"
echo "jumlah baris: $(printf '%s\n' "$isi" | wc -l)"
AKHIR
mkdir -p data
cp karyawan.txt data/
bash ringkas.shOutput yang Dihasilkan:
nama file : karyawan.txt
folder : data
jumlah baris: 4Mari kita bedah isi ringkas.sh baris per barisnya:
- Baris 2 (
berkas="data/karyawan.txt"): menyimpan path yang akan diolah — dalam praktik nilai ini biasanya datang dari$1, argumen pemanggil dari Chapter Arguments dan Command Line Options. - Baris 3-4 (
basename/dirname): memecah path menjadikaryawan.txtdandata; keduanya tidak menyentuh file sungguhan, murni mengolah string. - Baris 5 (
isi=$(cat ...)): menampung seluruh isi file ke satu variabel, lengkap dengan baris-barisnya. - Baris 8 (
printf '%s\n' ... | wc -l): mencetak ulang isi variabel lalu menghitung barisnya —printf '%s\n'dipilih agar ada baris terakhir yang diakhiri newline, menjaga hitunganwc -ltetap benar.
Kombinasi alat-alat ini menutup kebutuhan harian skrip: memotong kolom, meringkas, memfilter, lalu merapikan hasilnya. Yang masih membatasi kekuatan kita adalah pola pencarian yang selama ini hanya berupa teks literal — batas itu diangkat oleh regular expressions, bintang tamu Chapter berikutnya.