jq 是切片、過濾與轉換 JSON 的標準命令列工具。它把一行命令變成處理 API 回應、log 檔案與設定的強大查詢語言。本教學涵蓋安裝、你每天會用到的核心 filter,以及一組針對最常見實際任務的可複製貼上 recipe。
什麼是 jq?
jq 從檔案或標準輸入讀取 JSON,套用一個 filter,再把 JSON(或純文字)寫到標準輸出。預設會格式化輸出,而且絕不會把你的資料送到任何地方 —— 它是個本地端二進位檔,處理敏感 payload 也很合適。完整的過濾語言記錄在 jq 手冊 中。
安裝 jq
# macOS
brew install jq
# Debian / Ubuntu
sudo apt-get install jq
# Windows (winget or choco)
winget install jqlang.jq
# 驗證
jq --version
Identity Filter:隨手格式化
最簡單的 filter . 會原樣回傳輸入 —— 這就讓 jq 成了一個即時格式化工具:
# 格式化一個檔案
jq . data.json
# 格式化 curl 的回應
curl -s https://api.example.com/users | jq .
# 反過來壓縮(緊湊輸出)
jq -c . data.json
選取欄位
用 .key 鑽進物件,用 [] 鑽進陣列:
echo '{"user":{"name":"Ada","age":36}}' | jq '.user.name'
# "Ada"
# 陣列的全部元素
echo '[{"id":1},{"id":2}]' | jq '.[]'
# {"id":1}
# {"id":2}
# 從每個陣列元素取出一個欄位
echo '[{"id":1,"name":"Ada"},{"id":2,"name":"Bob"}]' | jq '.[].name'
# "Ada"
# "Bob"
# 用 -r 去掉 JSON 的引號(raw output)
jq -r '.[].name' users.json
用 select 過濾
# 只保留符合條件的物件
echo '[{"name":"Ada","active":true},{"name":"Bob","active":false}]' \
| jq '.[] | select(.active == true)'
# {"name":"Ada","active":true}
# 數值比較
jq '.[] | select(.age > 30)' users.json
用 map 和物件建構來變形
# 把每個元素重新組合成新物件
echo '[{"id":1,"name":"Ada","email":"a@x.com"}]' \
| jq 'map({ userId: .id, label: .name })'
# [{"userId":1,"label":"Ada"}]
# 抽出一個扁平的值列表
jq '[.[].email]' users.json # ["a@x.com", ...]
# 用 | 把 filter 串起來
jq '.items | map(.price) | add' order.json # 所有價格之和
常用 Recipe
| 任務 | 指令 |
|---|---|
| 格式化 | jq . file.json |
| 壓縮 | jq -c . file.json |
| 取一個欄位 | jq '.data.token' resp.json |
| Raw 字串(不帶引號) | jq -r '.token' resp.json |
| 計算陣列長度 | `jq '. |
| 物件的所有 key | jq 'keys' obj.json |
| 過濾行 | `jq '.[] |
| 依欄位排序 | jq 'sort_by(.age)' |
| 加總一個欄位 | `jq '[.[].amount] |
| 排序物件的 key | jq --sort-keys . file.json |
| 驗證(透過 exit code) | jq empty file.json |
重塑物件:to_entries / from_entries
jq 裡兩個最有用的物件形狀變換工具:
# 重新命名每個 key(這裡轉小寫)
echo '{"Name":"Ada","Active":true}' \
| jq 'with_entries(.key |= ascii_downcase)'
# → {"name":"Ada","active":true}
# 丟掉值為 null 的 key
jq 'with_entries(select(.value != null))' file.json
# 物件 ⇄ 鍵值對陣列
jq 'to_entries' file.json # → [{"key":"name","value":"Ada"}, ...]
jq 'from_entries' pairs.json # → {"name":"Ada", ...}
插值與輸出格式:\(.x)、@csv、@json、@base64
jq 內建字串插值與 格式字串,可以把 JSON 轉成其他格式:
# 在引號字串裡做字串插值
jq -r '"\(.user) bought \(.items|length) items"' order.json
# 每個物件一列 CSV
jq -r '.[] | [.id, .name, .total] | @csv' orders.json
# 內聯 JSON 給 shell 用(轉義過的字串字面值)
jq -r '.user | @json' record.json
# Base64 編碼一個值(處理 token / data URI 很方便)
jq -r '.payload | @base64' message.json
# 解碼這邊:較新版 jq 支援 @base64d
用 jq 驗證 JSON
因為 jq 遇到非法輸入時 exit code 非零,jq empty file.json 是腳本與 CI 裡乾淨俐落的合法性檢查 —— 更多驗證方法見 如何驗證 JSON。
什麼時候瀏覽器工具更快
jq 在腳本與 pipeline 裡很出彩,但對於一次性的小事 —— 格式化貼過來的回應、檢視一個陌生的結構、修復壞掉的 JSON —— 瀏覽器工具不用安裝、也不用做 shell 轉義:
- JSON Fix —— 一步搞定格式化與修復
- JSON Viewer —— 把大回應當成可折疊的樹狀結構檢視
- 如何格式化 JSON —— 在程式碼裡與命令列裡格式化
常見問題
怎麼用 jq 格式化 JSON?
執行 jq . file.json —— identity filter . 回傳輸入,而 jq 預設會格式化輸出。要緊湊輸出就用 -c。
怎麼用 jq 抽出單一欄位?
用路徑 filter,例如 jq '.data.token',再加上 -r 就能拿到不帶引號的 raw 值。
怎麼用 jq 過濾 JSON 陣列?
用 .[] 走訪,再用 select(),例如 jq '.[] | select(.active == true)'。
jq 能驗證 JSON 嗎?
可以 —— jq empty file.json 解析輸入,如果非法就以非零 exit code 結束,在 CI 裡很實用。詳情見 如何驗證 JSON。
怎麼用 jq 更新 JSON 裡的值?
用 = 指派(例如 jq '.status = "done"'),或用 |= 在目前的值上變換(例如 jq '.count |= . + 1')。jq 寫到標準輸出,所以要透過暫存檔把變更寫回——沒有原地編輯的開關。
怎麼把 shell 變數傳給 jq?
字串用 --arg name "$value"(數字和布林值用 --argjson),然後在過濾器裡用 $name 參照。這樣傳值比把它拼進過濾器字串更安全——拼進去時,一個孤立的引號就可能把它弄壞。
繼續閱讀
- 如何格式化 JSON —— jq、JavaScript、Python 與瀏覽器格式化
- 如何壓縮 JSON —— 用
jq -c等方式取得緊湊輸出 - 如何驗證 JSON —— 包括在 CI 裡用
jq empty - JSON Viewer —— 檢視 JSON 的瀏覽器替代方案
來源
- jq 手冊 — jq 過濾語言的官方參考
- 下載 jq — macOS、Linux 與 Windows 的安裝說明
- DigitalOcean — How To Transform JSON Data with jq
最後審閱:2026 年 6 月。