Kamu baru saja curl sebuah API, dan terminal memuntahkan satu baris JSON sepanjang 4.000 karakter. Scroll ke kanan tidak membantu, membuka file-nya di editor lalu menebak-nebak strukturnya juga buang waktu. jq menyelesaikan ini: tool baris perintah untuk memotong, memfilter, dan mengubah JSON langsung di terminal, dalam satu baris.

Kita akan memakai GitHub API sebagai bahan latihan karena gratis dan tidak butuh token untuk membaca data publik. Kalau konsep REST API masih asing, mulai dari Apa Itu REST API dan Bagaimana Cara Kerjanya? dulu — memahami kenapa JSON jadi format standar akan membuat tutorial ini jauh lebih masuk akal.

Instalasi

jq tersedia di hampir semua distro Linux dan bisa dipasang lewat satu perintah. macOS lewat Homebrew, Windows lewat Chocolatey.

bash
# Debian / Ubuntu
sudo apt install jq

# macOS
brew install jq

# Windows (Chocolatey)
choco install jq

Cek pemasangan dengan jq --version. Kalau muncul nomor versi, kamu sudah siap.

Pretty-print: JSON Panjang Menjadi Terbaca

Perintah paling mendasar jq adalah tanda titik .. Titik mewakili seluruh dokumen input, dan saat tidak ada filter lain, jq cukup memformat ulang JSON-nya dengan indentasi yang rapi.

bash
curl -s https://api.github.com/repos/jqlang/jq | jq '.'

Bandingkan dengan output curl mentah yang menempel jadi satu baris. Sekarang field-nya terpisah per baris, dan kalau terminal-mu mendukung warna, key akan tampil beda dari value. Langkah kecil ini saja biasanya sudah cukup untuk memahami bentuk respons API yang baru kamu lihat.

Mengambil Field Tertentu

Field diambil dengan notasi titik. Untuk objek bertingkat, tinggal sambung titiknya. Tidak ada koma, tidak ada kurawal, hanya .nama_field.

bash
curl -s https://api.github.com/repos/jqlang/jq | jq '.full_name'
# "jqlang/jq"

curl -s https://api.github.com/repos/jqlang/jq | jq '.stargazers_count'
# 33000

Perhatikan tanda kutip ganda yang masih menempel di hasil .full_name. Tambahkan flag -r (raw output) untuk membuangnya: jq -r '.full_name' mengembalikan jqlang/jq tanpa kutip. Ini wajib kalau hasilnya mau kamu simpan ke variabel shell atau kirim ke perintah lain.

Membuka Array dengan .[]

Banyak endpoint mengembalikan array. Untuk memproses elemennya satu per satu, kamu butuh .[]. Tanpa operator ini, jq menerapkan filter ke seluruh array sekaligus dan hasilnya sering jadi null.

bash
# nama semua repo milik akun jqlang
curl -s https://api.github.com/users/jqlang/repos | jq '.[] | .name'

# elemen pertama, terakhir, dan tiga elemen pertama
curl -s https://api.github.com/users/jqlang/repos | jq '.[0].name'
curl -s https://api.github.com/users/jqlang/repos | jq '.[-1].name'
curl -s https://api.github.com/users/jqlang/repos | jq '.[0:3] | map(.name)'

Tanda | di dalam jq adalah pipe internal, bukan pipe shell. Ia mengirim hasil dari sisi kiri ke filter di sisi kanan. Notasi .[-1] mengambil elemen terakhir, mirip indeks negatif di Python.

Menyaring Data dengan select()

select() mempertahankan elemen yang lolos kondisi, mirip klausa WHERE di SQL. Gabungkan dengan .[] untuk menyaring array objek.

bash
# repo dengan lebih dari 1.000 bintang
curl -s https://api.github.com/users/jqlang/repos \
  | jq '.[] | select(.stargazers_count > 1000) | .full_name'

Operand perbandingan di jq sama seperti bahasa lain: >, <, ==, dan !=. Kamu bisa menyambung beberapa select() atau memakai and / or untuk kondisi majemuk.

Membangun Objek Baru

Kamu jarang butuh seluruh field dari respons. Bangun objek baru dengan kurawal {} dan beri nama key sesukamu.

bash
curl -s https://api.github.com/repos/jqlang/jq \
  | jq '{nama: .full_name, bintang: .stargazers_count, bahasa: .language}'

# {
#   "nama": "jqlang/jq",
#   "bintang": 33000,
#   "bahasa": "C"
# }

Agregasi: sort_by, map, dan add

Tiga fungsi ini menutupi sebagian besar kebutuhan transformasi: map() menerapkan filter ke tiap elemen, sort_by() mengurutkan, dan add menjumlahkan array angka.

bash
# tiga repo dengan bintang terbanyak
curl -s https://api.github.com/users/jqlang/repos \
  | jq 'sort_by(.stargazers_count) | reverse | .[0:3] | map(.full_name)'

# total bintang seluruh repo
curl -s https://api.github.com/users/jqlang/repos \
  | jq 'map(.stargazers_count) | add'

Memakai jq di Dalam Skrip Bash

jq paling berguna saat digabung dengan bash. Simpan hasil filter ke variabel dan pakai di logika skrip — pola yang saya pakai hampir setiap hari untuk otomasi server. Kalau kamu belum nyaman menulis skrip shell, mulai dari Menguasai Bash Scripting di Linux.

bash
#!/usr/bin/env bash
# cek_repo.sh <owner/repo>
REPO="$1"
RESPONSE=$(curl -s "https://api.github.com/repos/$REPO")

STARS=$(echo "$RESPONSE" | jq -r '.stargazers_count')
NAME=$(echo "$RESPONSE" | jq -r '.full_name')

if [ "$STARS" = "null" ]; then
  echo "Repo tidak ditemukan"
  exit 1
fi

echo "$NAME punya $STARS bintang"

Jalankan dengan bash cek_repo.sh jqlang/jq. Perhatikan -r di sini: tanpa flag itu, variabel STARS berisi angka dengan tanda kutip yang masih menempel, dan perbandingan terhadap null bisa meleset.

Kalau kamu mau mencoba filter tanpa instalasi dulu, buka jqplay.org. Tempel JSON dan filter di sana, hasilnya muncul seketika. Saya pakai ini untuk menguji filter rumit sebelum menempelkannya ke skrip produksi.

jq tidak menggantikan Python, ia melengkapinya. Untuk pemrosesan yang lebih berat — parsing puluhan ribu baris atau menyimpan hasil ke database — pindah ke skrip Python dan panggil API lewat httpx. Untuk jawaban cepat di terminal, jq tetap alat pertama yang saya buka.