jq One-Liners Filtrasi dan Transformasi JSON dari CLI Tanpa Menulis Skrip
Tujuh resep praktis jq untuk pengembang backend dan DevOps — mencakup select, map, to_entries, del, group_by, dan transformasi API nyata. Input dan output ditampilkan untuk setiap pola.
Anda sedang melihat respons API yang telah dikompresi di terminal Anda. Anda perlu mengekstrak tiga field, menghilangkan nilai nol, dan mengalirkan hasilnya ke sesuatu yang lain. Menulis skrip Python untuk hal ini membutuhkan 20 baris dan 2 menit yang tidak Anda miliki. jq mengatasinya dalam satu perintah — jika Anda tahu pola-polinnya.
Tujuh resep di bawah ini. Setiap resep mencakup pola yang sering Anda temui saat bekerja dengan respons API atau file log. Input, perintah, dan output ditampilkan untuk setiap resep.
Instalasi
brew install jq # macOS
apt-get install jq # Ubuntu/Debian
apk add jq # Alpine (Docker images)
Resep 1: Ekstrak Field dari Setiap Objek dalam Array
Hal yang paling umum yang akan Anda lakukan dengan jq: mengambil satu field dari setiap item dalam array JSON.
Input (users.json)
[
{"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"},
{"id": 2, "name": "Bob", "email": "bob@example.com", "role": "user"},
{"id": 3, "name": "Carol", "email": "carol@example.com", "role": "user"}
]
jq '.[].name' users.json
# → "Alice"
# "Bob"
# "Carol" (newline-separated stream)
.[] mengiterasi setiap elemen dalam array; .name mengambil field tersebut. Outputnya adalah aliran — berguna untuk dialirkan ke perintah lain. Jika Anda membutuhkan array JSON yang benar:
jq 'map(.name)' users.json
# → ["Alice", "Bob", "Carol"]
map(.name) adalah singkatan dari [.[] | .name] — mengaplikasikan ekspresi pada setiap item dan mengelompokkan hasilnya dalam array. Anda akan menggunakan map() sangat sering.
Resep 2: Filter dengan select
Hanya simpan objek yang memenuhi kondisi; buang yang lain.
jq 'map(select(.role == "admin"))' users.json
[
{"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"}
]
select(expr) mengalirkan item hanya ketika ekspresi bernilai benar — semua yang lain menghilang. Mengelompokkannya dalam map() mengawetkan output sebagai array. Contoh lain:
# Numeric comparison
jq 'map(select(.score > 80))' results.json
# Not-null check
jq 'map(select(.error != null))' events.json
# String contains (requires test)
jq 'map(select(.message | test("timeout")))' logs.json
Resep 3: Mengubah Objek dengan map
Pilih hanya field yang Anda butuhkan dan secara opsional beri nama ulang dalam satu langkah.
jq 'map({name: .name, role: .role})' users.json
[
{"name": "Alice", "role": "admin"},
{"name": "Bob", "role": "user"},
{"name": "Carol", "role": "user"}
]
Anda sedang membuat literal objek baru untuk setiap item. Untuk mengubah nama key, ubah sisi kiri tanda titik koma:
jq 'map({username: .name, access_level: .role})' users.json
Satu singkatan yang menghemat ketik: {name} setara dengan {name: .name}. Jika Anda ingin field tetap seperti aslinya, Anda tidak perlu menulis kunci dua kali:
jq 'map({id, name, role})' users.json
Resep 4: Ubah Nama Key dengan to_entries dan from_entries
map sangat baik ketika Anda tahu kunci-kunci yang ada. Ketika Anda perlu mengubah kunci-kunci itu sendiri — menambahkan awalan, mengubah konvensi nama, atau mengubah nama berdasarkan lookup — to_entries adalah pola yang tepat.
Input (config.json)
{"api_url": "https://api.example.com", "timeout": 30, "retry_count": 3}
# Add cfg_ prefix to every key
jq 'to_entries | map(.key = "cfg_" + .key) | from_entries' config.json
{"cfg_api_url": "https://api.example.com", "cfg_timeout": 30, "cfg_retry_count": 3}
to_entries mengubah {"k": "v"} ke dalam [{"key": "k", "value": "v"}]. Setelah Anda memodifikasi entri-entri dalam array hasilnya, from_entries mengembangkan kembali objek tersebut. Untuk mengubah satu kunci tertentu tanpa mengganggu yang lain:
jq 'to_entries | map(if .key == "api_url" then .key = "endpoint" else . end) | from_entries' config.json
Resep 5: Hapus Field dengan del
Inversi dari pengubahan: simpan semua dan hapus beberapa field tertentu. Kasus utamanya adalah menghapus data sensitif sebelum mencatat atau sebelum mengirimkan payload ke layanan pihak ketiga.
jq 'map(del(.email))' users.json
[
{"id": 1, "name": "Alice", "role": "admin"},
{"id": 2, "name": "Bob", "role": "user"},
{"id": 3, "name": "Carol", "role": "user"}
]
Hapus beberapa field secara bersamaan, atau hapus jalur yang terdalam:
# Multiple top-level fields at once
jq 'del(.password, .token, .refresh_token)' user.json
# Nested path
jq 'del(.user.internal_id)' response.json
# All fields named "debug" at any depth (recursive descent)
jq 'del(.. | .debug? // empty)' response.json
Resep 6: Filter, Ubah, dan Urutkan dalam Satu Langkah
Manfaat utamanya adalah menggabungkan primitif-primitif ini. Berikut adalah pola yang sering muncul saat bekerja dengan respons API yang dibagi-bagi: turun ke array yang terdalam, filter, ubah objek-objeknya, dan urutkan hasilnya.
Input (repos.json)
{
"total_count": 3,
"items": [
{"id": 1, "name": "repo-alpha", "stargazers_count": 142, "language": "Go", "private": false},
{"id": 2, "name": "repo-beta", "stargazers_count": 89, "language": "Python", "private": true},
{"id": 3, "name": "repo-gamma", "stargazers_count": 310, "language": "Go", "private": false}
]
}
jq '.items
| map(select(.private == false and .language == "Go"))
| sort_by(-.stargazers_count)
| map({name, stars: .stargazers_count})' repos.json
[
{"name": "repo-gamma", "stars": 310},
{"name": "repo-alpha", "stars": 142}
]
Alur pipeline:
.items— turun ke array yang terdalammap(select(...))— filter dalam satu langkah;andmenggabungkan kondisisort_by(-.stargazers_count)— menolak nilai untuk pengurutan menurun;sort_by(.field)satu sendiri memberikan pengurutan naikmap({name, stars: .stargazers_count})— penyesuaian akhir;{name}adalah singkatan dari{name: .name}
Resep 7: Hitung Tingkat Log dengan group_by
Analisis frekuensi pada output log terstruktur — tidak perlu database, tidak perlu teknik awk.
Input (logs.json)
[
{"level": "error", "msg": "connection timeout", "service": "auth"},
{"level": "info", "msg": "request received", "service": "api"},
{"level": "error", "msg": "null pointer exception", "service": "worker"},
{"level": "warn", "msg": "slow query detected", "service": "db"},
{"level": "error", "msg": "rate limit exceeded", "service": "api"}
]
jq 'group_by(.level) | map({level: .[0].level, count: length}) | sort_by(-.count)' logs.json
[
{"level": "error", "count": 3},
{"level": "info", "count": 1},
{"level": "warn", "count": 1}
]
group_by(.level) mengembalikan array dari array — setiap sub-array mengandung semua entri yang memiliki nilai tingkat yang sama. .[0].level mengambil nama tingkat dari item pertama dalam kelompok; length menghitung jumlah entri dalam kelompok tersebut.
Tambahkan pemecahan per-layanan dalam query yang sama:
jq 'group_by(.level) | map({
level: .[0].level,
count: length,
services: map(.service) | unique
})' logs.json
Rincian Singkat
Pola-pola di atas dalam bentuk tabel untuk saat Anda membutuhkan pengingat cepat:
| Apa yang Anda inginkan | Ekspresi jq |
|---|---|
| Semua nilai dari field | map(.field) |
| Filter item yang sesuai | map(select(.field == "val")) |
| Ubah setiap objek | map({newKey: .oldKey}) |
| Ubah semua kunci | to_entries | map(.key = ...) | from_entries |
| Hapus field | map(del(.field1, .field2)) |
| Urutkan naik | sort_by(.field) |
| Urutkan turun | sort_by(-.field) |
| Hitung berdasarkan kelompok | group_by(.field) | map({key: .[0].field, count: length}) |
| Dapatkan semua kunci dari objek | keys |
| Hitung jumlah item dalam array | length |
| Nilai unik dari field | map(.field) | unique |
Sebelum Anda Mulai: Kendalikan Blok
Respons API sering kali kembali dalam bentuk kompresi atau sangat terdalam. Jika Anda tidak yakin tentang jalur yang dibutuhkan, tempelkan JSON ke dalam Pemformat JSON — ini membuat tampilan rapi dengan node yang dapat dikompresi sehingga Anda dapat melihat jalur sebelum menulis ekspresi jq . Setelah menjalankan transformasi, alat ini berguna untuk memverifikasi perbedaan sebelum dan sesudah ketika Anda sedang mengubah atau menghapus field dan ingin memastikan tidak ada perubahan yang tidak diinginkan. Bandingkan JSON Tujuh pola ini mencakup sebagian besar pekerjaan mengolah JSON yang Anda lakukan di baris perintah. Keunggulan nyata adalah menggabungkannya — setelah Anda dapat melakukan filter, ubah, dan urutkan, Anda dapat memproses kebanyakan respons API tanpa menyentuh file skrip.
jq One-Liners: Filter dan Transformasi JSON dari CLI Tanpa Menulis Skrip 2
Instal Ekstensi Kami
Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat
恵 Papan Skor Telah Tiba!
Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!
Alat Wajib Coba
Lihat semua Pendatang baru
Lihat semuaMemperbarui: Kita alat terbaru ditambahkan pada 7 Juni 2026
