DevToolBox免费
博客

jq 命令教程与示例

12 分钟阅读作者 DevToolBox

jq 是一个轻量级、灵活的命令行 JSON 处理器,已经成为每个与 API、配置文件或日志数据打交道的开发者不可或缺的工具。这份全面的教程涵盖了从基本过滤器到高级数据转换的 jq 命令示例,帮助你掌握终端中的 JSON 处理。

使用我们的在线 JSON 格式化工具格式化和查看 JSON →

1. 什么是 jq?

jq 就像 JSON 数据的 sed —— 一个命令行工具,让你可以轻松地切片、过滤、映射和转换结构化数据。它用 C 语言编写,零运行时依赖,因此在所有主要平台上都快速且可移植。

jq 接受 JSON 输入(来自文件或标准输入),应用一个或多个过滤器,并产生 JSON 输出。它的表达式语言强大而简洁,允许在单个命令中完成复杂的数据转换。

安装

在任何平台上几秒内安装 jq:

# Ubuntu / Debian
sudo apt-get install jq

# macOS (Homebrew)
brew install jq

# Windows (Chocolatey)
choco install jq

# Windows (Scoop)
scoop install jq

# Alpine Linux
apk add jq

# From source / binary
# Download from https://jqlang.github.io/jq/download/
wget https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64
chmod +x jq-linux-amd64 && sudo mv jq-linux-amd64 /usr/local/bin/jq

# Verify installation
jq --version

基本语法

最简单的 jq 命令是恒等过滤器 .,它会美化打印 JSON 输入:

# Pretty-print JSON (identity filter)
echo '{"name":"Alice","age":30,"skills":["go","rust"]}' | jq '.'

# Output:
# {
#   "name": "Alice",
#   "age": 30,
#   "skills": [
#     "go",
#     "rust"
#   ]
# }

# Read from a file
jq '.' data.json

# Compact output (single line)
jq -c '.' data.json

# Raw string output (no quotes)
echo '{"name":"Alice"}' | jq -r '.name'
# Output: Alice  (without quotes)

# Sort keys alphabetically
echo '{"z":1,"a":2,"m":3}' | jq -S '.'

2. 基本过滤器

jq 过滤器从 JSON 输入中提取和转换数据。点表示法是 jq 中一切的基础。

Object Field Access

# Sample JSON
# {"name": "Alice", "age": 30, "address": {"city": "NYC", "zip": "10001"}}

# Access a top-level field
echo '{"name":"Alice","age":30}' | jq '.name'
# "Alice"

# Access a nested field
echo '{"address":{"city":"NYC","zip":"10001"}}' | jq '.address.city'
# "NYC"

# Multiple fields (comma-separated)
echo '{"name":"Alice","age":30,"role":"admin"}' | jq '.name, .age'
# "Alice"
# 30

# Optional field access (no error if missing)
echo '{"name":"Alice"}' | jq '.email?'
# null

# Field with special characters (use quotes)
echo '{"my-field": 42}' | jq '.["my-field"]'
# 42

Array Access

# Access by index
echo '[10,20,30,40,50]' | jq '.[0]'
# 10

# Negative index (from end)
echo '[10,20,30,40,50]' | jq '.[-1]'
# 50

# Array slice
echo '[10,20,30,40,50]' | jq '.[1:3]'
# [20, 30]

# Slice from start
echo '[10,20,30,40,50]' | jq '.[:2]'
# [10, 20]

# Slice to end
echo '[10,20,30,40,50]' | jq '.[3:]'
# [40, 50]

# Iterate all elements (array value iterator)
echo '[1,2,3]' | jq '.[]'
# 1
# 2
# 3

# Iterate object values
echo '{"a":1,"b":2,"c":3}' | jq '.[]'
# 1
# 2
# 3

Constructing New Objects & Arrays

# Build a new object from fields
echo '{"first":"Alice","last":"Smith","age":30}' | jq '{name: .first, years: .age}'
# {"name": "Alice", "years": 30}

# Wrap results in an array
echo '{"a":1,"b":2,"c":3}' | jq '[.a, .b, .c]'
# [1, 2, 3]

# Collect iterator results into an array
echo '[1,2,3,4,5]' | jq '[.[] | . * 2]'
# [2, 4, 6, 8, 10]

3. 管道与链接

就像 Unix shell 管道一样,jq 使用 | 将过滤器链接在一起。左侧过滤器的输出成为右侧过滤器的输入。这种可组合性是 jq 如此强大的原因。

# Chain filters with pipe
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25}]}' | \
  jq '.users[] | .name'
# "Alice"
# "Bob"

# Multiple pipes
echo '{"data":{"items":[{"id":1,"val":"a"},{"id":2,"val":"b"}]}}' | \
  jq '.data.items[] | .val'
# "a"
# "b"

# Pipe into object construction
echo '{"users":[{"first":"Alice","last":"Smith"},{"first":"Bob","last":"Jones"}]}' | \
  jq '.users[] | {full_name: (.first + " " + .last)}'
# {"full_name": "Alice Smith"}
# {"full_name": "Bob Jones"}

# Pipe with length
echo '{"users":[{"name":"Alice"},{"name":"Bob"},{"name":"Charlie"}]}' | \
  jq '.users | length'
# 3

# Pipe with multiple outputs
echo '{"a":{"x":1},"b":{"x":2}}' | jq '.a, .b | .x'
# 1
# 2

# Parentheses for grouping
echo '{"a":1,"b":2}' | jq '(.a + .b) * 2'
# 6

4. 选择与过滤

select() 函数根据条件过滤元素。与 map() 结合使用,它成为 JSON 数据的强大查询引擎。

# select() - filter by condition
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25},{"name":"Charlie","age":35}]' | \
  jq '.[] | select(.age > 28)'
# {"name": "Alice", "age": 30}
# {"name": "Charlie", "age": 35}

# map(select()) - filter and keep as array
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25},{"name":"Charlie","age":35}]' | \
  jq 'map(select(.age >= 30))'
# [{"name": "Alice", "age": 30}, {"name": "Charlie", "age": 35}]

# String matching with select
echo '[{"name":"Alice"},{"name":"Bob"},{"name":"Anna"}]' | \
  jq '.[] | select(.name | startswith("A"))'
# {"name": "Alice"}
# {"name": "Anna"}

# select with contains
echo '[{"tags":["go","api"]},{"tags":["python","ml"]},{"tags":["go","cli"]}]' | \
  jq '.[] | select(.tags | contains(["go"]))'
# {"tags": ["go", "api"]}
# {"tags": ["go", "cli"]}

# select with test (regex)
echo '[{"email":"alice@gmail.com"},{"email":"bob@company.org"},{"email":"charlie@gmail.com"}]' | \
  jq '.[] | select(.email | test("gmail"))'
# {"email": "alice@gmail.com"}
# {"email": "charlie@gmail.com"}

# has() - check if key exists
echo '{"name":"Alice","email":"alice@example.com"}' | jq 'has("email")'
# true

echo '[{"name":"Alice","email":"a@b.com"},{"name":"Bob"}]' | \
  jq '.[] | select(has("email"))'
# {"name": "Alice", "email": "a@b.com"}

# in() - check if key exists in object
echo '{"admin":true,"user":true}' | jq '"admin" | in({"admin":true,"user":true})'
# true

# type checks
echo '[1,"hello",null,true,[],{}]' | jq '.[] | select(type == "string")'
# "hello"

# Negated select (NOT matching)
echo '[{"status":"active"},{"status":"inactive"},{"status":"active"}]' | \
  jq '.[] | select(.status != "active")'
# {"status": "inactive"}

5. 字符串插值与格式化

jq 在双引号内提供 \(expr) 字符串插值,还有多种格式字符串用于将数据转换为不同的输出格式。

# String interpolation with \()
echo '{"name":"Alice","age":30}' | jq '"\(.name) is \(.age) years old"'
# "Alice is 30 years old"

# Use -r for raw output (no surrounding quotes)
echo '{"name":"Alice","age":30}' | jq -r '"\(.name) is \(.age) years old"'
# Alice is 30 years old

# @text - plain text (default)
echo '"hello"' | jq '@text'
# "hello"

# @html - HTML-escaped
echo '"<script>alert(1)</script>"' | jq '@html'
# "&lt;script&gt;alert(1)&lt;/script&gt;"

# @csv - CSV format (use with -r)
echo '["Alice",30,"NYC"]' | jq -r '@csv'
# "Alice",30,"NYC"

# @tsv - Tab-separated values
echo '["Alice",30,"NYC"]' | jq -r '@tsv'
# Alice	30	NYC

# @json - JSON-encode a string
echo '"hello world"' | jq '@json'
# ""hello world""

# @base64 - Base64 encode
echo '"hello world"' | jq '@base64'
# "aGVsbG8gd29ybGQ="

# @base64d - Base64 decode
echo '"aGVsbG8gd29ybGQ="' | jq '@base64d'
# "hello world"

# @uri - URI-encode
echo '"hello world&foo=bar"' | jq '@uri'
# "hello%20world%26foo%3Dbar"

# Combining formats: CSV from array of arrays
echo '[[1,"Alice",30],[2,"Bob",25]]' | jq -r '.[] | @csv'
# 1,"Alice",30
# 2,"Bob",25

# Build formatted table with string interpolation
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25}]' | \
  jq -r '.[] | "\(.name)\t\(.age)"'
# Alice	30
# Bob	25

6. 数组操作

jq 提供了丰富的内置函数来处理数组:排序、分组、过滤、展平等。

# length
echo '[1,2,3,4,5]' | jq 'length'
# 5

# map() - transform each element
echo '[1,2,3,4,5]' | jq 'map(. * 10)'
# [10, 20, 30, 40, 50]

echo '[{"name":"Alice"},{"name":"Bob"}]' | jq 'map(.name)'
# ["Alice", "Bob"]

# sort and sort_by
echo '[3,1,4,1,5,9,2,6]' | jq 'sort'
# [1, 1, 2, 3, 4, 5, 6, 9]

echo '[{"name":"Charlie","age":35},{"name":"Alice","age":30},{"name":"Bob","age":25}]' | \
  jq 'sort_by(.age)'
# [{"name":"Bob","age":25},{"name":"Alice","age":30},{"name":"Charlie","age":35}]

# Reverse sort
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25},{"name":"Charlie","age":35}]' | \
  jq 'sort_by(.age) | reverse'

# group_by
echo '[{"dept":"eng","name":"Alice"},{"dept":"sales","name":"Bob"},{"dept":"eng","name":"Charlie"}]' | \
  jq 'group_by(.dept)'
# [[{"dept":"eng","name":"Alice"},{"dept":"eng","name":"Charlie"}],[{"dept":"sales","name":"Bob"}]]

# unique and unique_by
echo '[1,2,2,3,3,3]' | jq 'unique'
# [1, 2, 3]

echo '[{"city":"NYC"},{"city":"LA"},{"city":"NYC"}]' | jq 'unique_by(.city)'
# [{"city":"LA"},{"city":"NYC"}]

# flatten
echo '[[1,2],[3,[4,5]],6]' | jq 'flatten'
# [1, 2, 3, 4, 5, 6]

# flatten with depth
echo '[[1,[2]],[3,[4,[5]]]]' | jq 'flatten(1)'
# [1, [2], 3, [4, [5]]]

# first, last, nth
echo '[10,20,30,40,50]' | jq 'first'
# 10
echo '[10,20,30,40,50]' | jq 'last'
# 50

# min, max, min_by, max_by
echo '[3,1,4,1,5,9]' | jq 'min'
# 1
echo '[3,1,4,1,5,9]' | jq 'max'
# 9

echo '[{"name":"Alice","score":85},{"name":"Bob","score":92}]' | jq 'max_by(.score)'
# {"name": "Bob", "score": 92}

# add - sum numbers or concatenate arrays/strings
echo '[1,2,3,4,5]' | jq 'add'
# 15

echo '[["a","b"],["c","d"]]' | jq 'add'
# ["a", "b", "c", "d"]

# indices / index
echo '["a","b","c","b","a"]' | jq 'index("b")'
# 1

# limit and until
echo 'null' | jq '[limit(5; range(100))]'
# [0, 1, 2, 3, 4]

# range - generate number sequences
echo 'null' | jq '[range(5)]'
# [0, 1, 2, 3, 4]

echo 'null' | jq '[range(2;8;2)]'
# [2, 4, 6]

7. 对象操作

jq 使用 keysvaluesto_entrieswith_entries 等内置函数,可以轻松地检查、转换和重构 JSON 对象。

# keys - get all keys as sorted array
echo '{"name":"Alice","age":30,"city":"NYC"}' | jq 'keys'
# ["age", "city", "name"]

# keys_unsorted - preserve original order
echo '{"name":"Alice","age":30,"city":"NYC"}' | jq 'keys_unsorted'
# ["name", "age", "city"]

# values - get all values
echo '{"name":"Alice","age":30,"city":"NYC"}' | jq 'values'
# ["Alice", 30, "NYC"]

# to_entries - convert to key-value pair array
echo '{"name":"Alice","age":30}' | jq 'to_entries'
# [{"key": "name", "value": "Alice"}, {"key": "age", "value": 30}]

# from_entries - convert key-value pairs back to object
echo '[{"key":"name","value":"Alice"},{"key":"age","value":30}]' | jq 'from_entries'
# {"name": "Alice", "age": 30}

# from_entries also works with "name"/"value" pairs
echo '[{"name":"x","value":1},{"name":"y","value":2}]' | jq 'from_entries'
# {"x": 1, "y": 2}

# with_entries - transform entries (to_entries | map(f) | from_entries)
echo '{"name":"Alice","age":30}' | jq 'with_entries(.key = "prefix_" + .key)'
# {"prefix_name": "Alice", "prefix_age": 30}

# with_entries - filter by key
echo '{"name":"Alice","age":30,"_internal":true}' | \
  jq 'with_entries(select(.key | startswith("_") | not))'
# {"name": "Alice", "age": 30}

# Add / merge objects with +
echo '{"a":1,"b":2}' | jq '. + {"c":3,"d":4}'
# {"a": 1, "b": 2, "c": 3, "d": 4}

# Merge with override
echo '{"a":1,"b":2}' | jq '. + {"b":99}'
# {"a": 1, "b": 99}

# * for recursive merge
echo '{"a":{"x":1},"b":2}' | jq '. * {"a":{"y":2}}'
# {"a": {"x": 1, "y": 2}, "b": 2}

# del() - remove a key
echo '{"name":"Alice","age":30,"tmp":true}' | jq 'del(.tmp)'
# {"name": "Alice", "age": 30}

# del() multiple keys
echo '{"a":1,"b":2,"c":3,"d":4}' | jq 'del(.b, .d)'
# {"a": 1, "c": 3}

# Update a field with |=
echo '{"name":"alice","age":30}' | jq '.name |= ascii_upcase'
# {"name": "ALICE", "age": 30}

# Update nested field
echo '{"user":{"name":"Alice","score":85}}' | jq '.user.score |= . + 10'
# {"user": {"name": "Alice", "score": 95}}

8. 条件判断与错误处理

jq 支持 if-then-else 表达式、替代运算符 // 和 try-catch,用于构建健壮的数据处理管道。

# if-then-else
echo '{"age":25}' | jq 'if .age >= 18 then "adult" else "minor" end'
# "adult"

# if-then-elif-else
echo '{"score":85}' | jq '
  if .score >= 90 then "A"
  elif .score >= 80 then "B"
  elif .score >= 70 then "C"
  else "F"
  end'
# "B"

# if-then-else with map
echo '[{"name":"Alice","age":30},{"name":"Bob","age":15}]' | \
  jq 'map(if .age >= 18 then . + {"status":"adult"} else . + {"status":"minor"} end)'
# [{"name":"Alice","age":30,"status":"adult"},{"name":"Bob","age":15,"status":"minor"}]

# Alternative operator // (default value if null or false)
echo '{"name":"Alice"}' | jq '.email // "not set"'
# "not set"

echo '{"name":"Alice","email":"alice@example.com"}' | jq '.email // "not set"'
# "alice@example.com"

# Nested alternative
echo '{"config":{}}' | jq '.config.timeout // .config.default_timeout // 30'
# 30

# try-catch (jq 1.6+)
echo '"not a number"' | jq 'try tonumber catch "invalid number"'
# "invalid number"

# try without catch (silently suppress errors)
echo '{"a":1}' | jq 'try .b.c.d'
# (no output, no error)

# try with array of mixed types
echo '[1,"two",3,"four",5]' | jq '[.[] | try (. + 10)]'
# [11, 13, 15]

# Error handling with if and type
echo '{"value":"hello"}' | jq '
  if (.value | type) == "number" then .value * 2
  else "expected number, got \(.value | type)"
  end'
# "expected number, got string"

# empty - produce no output (useful in select-like patterns)
echo '[1,2,3,4,5]' | jq '.[] | if . > 3 then . else empty end'
# 4
# 5

9. 实战示例

以下是你在日常工作中使用 API、云服务和日志文件时会用到的实用 jq 模式。

Parse GitHub API Responses

# List repos - extract name, stars, and language
curl -s "https://api.github.com/users/torvalds/repos?per_page=5" | \
  jq '.[] | {name: .name, stars: .stargazers_count, lang: .language}'

# Find most starred repo
curl -s "https://api.github.com/users/torvalds/repos?per_page=100" | \
  jq 'max_by(.stargazers_count) | {name, stars: .stargazers_count}'

# List open issues with labels
curl -s "https://api.github.com/repos/jqlang/jq/issues?state=open&per_page=5" | \
  jq '.[] | {title: .title, labels: [.labels[].name], created: .created_at}'

# Count repos by language
curl -s "https://api.github.com/users/octocat/repos" | \
  jq 'group_by(.language) | map({lang: .[0].language, count: length}) | sort_by(.count) | reverse'

AWS CLI Output Processing

# List EC2 instances - extract ID, type, state
aws ec2 describe-instances | \
  jq '.Reservations[].Instances[] | {
    id: .InstanceId,
    type: .InstanceType,
    state: .State.Name,
    name: (.Tags // [] | map(select(.Key == "Name")) | first | .Value // "unnamed")
  }'

# Find running instances only
aws ec2 describe-instances | \
  jq '[.Reservations[].Instances[] | select(.State.Name == "running")] | length'

# List S3 buckets with creation dates
aws s3api list-buckets | \
  jq '.Buckets | sort_by(.CreationDate) | .[] | "\(.Name) - \(.CreationDate)"'

# Get Lambda function names and runtimes
aws lambda list-functions | \
  jq '.Functions[] | {name: .FunctionName, runtime: .Runtime, memory: .MemorySize}'

Log Processing

# Parse JSON log lines (one JSON object per line)
cat app.log | jq -r 'select(.level == "error") | "\(.timestamp) \(.message)"'

# Count errors by type
cat app.log | jq -s 'map(select(.level == "error")) | group_by(.error_code) |
  map({code: .[0].error_code, count: length}) | sort_by(.count) | reverse'

# Extract slow requests (>1s)
cat access.log | jq 'select(.response_time_ms > 1000) |
  {path: .request_path, time_ms: .response_time_ms, method: .method}'

# Aggregate stats from JSON logs
cat app.log | jq -s '{
  total: length,
  errors: map(select(.level == "error")) | length,
  avg_response_ms: (map(.response_time_ms) | add / length),
  unique_users: (map(.user_id) | unique | length)
}'

Docker & Kubernetes

# Docker: list containers with ports
docker inspect $(docker ps -q) | \
  jq '.[] | {name: .Name, image: .Config.Image, ports: .NetworkSettings.Ports}'

# Docker: get container IP addresses
docker network inspect bridge | \
  jq '.[0].Containers | to_entries[] | {name: .value.Name, ip: .value.IPv4Address}'

# Kubernetes: get pod names and status
kubectl get pods -o json | \
  jq '.items[] | {name: .metadata.name, status: .status.phase, restarts: (.status.containerStatuses[0].restartCount // 0)}'

# Kubernetes: find pods not in Running state
kubectl get pods -o json | \
  jq '[.items[] | select(.status.phase != "Running") | .metadata.name]'

10. jq 与 curl 配合使用

curl | jq 管道是 API 开发中最常见的模式之一。将 API 响应直接通过管道传递给 jq,即可立即格式化和提取数据。

# Basic: pretty-print API response
curl -s https://api.github.com/users/octocat | jq '.'

# Extract specific fields
curl -s https://api.github.com/users/octocat | jq '{name, bio, public_repos}'

# Process paginated API results
for page in 1 2 3; do
  curl -s "https://api.example.com/items?page=$page" | jq '.items[]'
done | jq -s 'length'

# POST then parse response
curl -s -X POST https://api.example.com/auth \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"secret"}' | \
  jq -r '.token'

# Chain: get token, then use it
TOKEN=$(curl -s -X POST https://api.example.com/auth \
  -d '{"user":"admin","pass":"secret"}' | jq -r '.token')
curl -s -H "Authorization: Bearer $TOKEN" https://api.example.com/data | jq '.'

# Save extracted data to file
curl -s https://api.github.com/users/octocat/repos | \
  jq '[.[] | {name, stars: .stargazers_count, url: .html_url}]' > repos.json

# Handle errors in API response
curl -s https://api.example.com/data | \
  jq 'if .error then "Error: \(.error.message)" else .data end'

# Headers + jq for debugging
curl -s -D- https://api.example.com/data | \
  sed '1,/^\r$/d' | jq '.'

# Multiple API calls with xargs
echo "octocat torvalds gvanrossum" | tr ' ' '\n' | \
  xargs -I {} curl -s "https://api.github.com/users/{}" | \
  jq '{login, name, public_repos}'

# GraphQL API with jq
curl -s -X POST https://api.github.com/graphql \
  -H "Authorization: bearer $GITHUB_TOKEN" \
  -d '{"query":"{ viewer { login name }}"}' | \
  jq '.data.viewer'

11. 高级 jq

对于复杂的数据转换,jq 提供了 reduce、foreach、自定义函数定义、环境变量和命令行参数。

reduce

# Sum with reduce
echo '[1,2,3,4,5]' | jq 'reduce .[] as $x (0; . + $x)'
# 15

# Build object from array with reduce
echo '[["name","Alice"],["age","30"],["city","NYC"]]' | \
  jq 'reduce .[] as $pair ({}; . + {($pair[0]): $pair[1]})'
# {"name": "Alice", "age": "30", "city": "NYC"}

# Running total with reduce
echo '[10,20,30,40]' | \
  jq 'reduce .[] as $x ([]; . + [((. | last) // 0) + $x])'
# [10, 30, 60, 100]

# Count occurrences with reduce
echo '["a","b","a","c","b","a"]' | \
  jq 'reduce .[] as $x ({}; .[$x] = ((.[$x] // 0) + 1))'
# {"a": 3, "b": 2, "c": 1}

foreach

# foreach produces intermediate results
echo 'null' | jq '[foreach range(5) as $x (0; . + $x)]'
# [0, 1, 3, 6, 10]

# foreach with extract expression
echo 'null' | jq '[foreach range(1;6) as $x (1; . * $x; .)]'
# [1, 2, 6, 24, 120]  (factorials)

Custom Functions (def)

# Define a reusable function
echo '["hello","world"]' | jq 'def capitalize: (.[0:1] | ascii_upcase) + .[1:]; map(capitalize)'
# ["Hello", "World"]

# Function with parameters
echo '[1,2,3,4,5]' | jq 'def clamp(min; max): if . < min then min elif . > max then max else . end; map(clamp(2;4))'
# [2, 2, 3, 4, 4]

# Recursive function
echo '{"a":{"b":{"c":{"d":"found"}}}}' | \
  jq 'def depth: if type == "object" then (to_entries | map(.value | depth) | max) + 1 elif type == "array" then (map(depth) | max) + 1 else 0 end; depth'
# 4

# Function for formatting bytes
echo '{"size":1073741824}' | jq 'def bytes:
  if . >= 1073741824 then "\(. / 1073741824 | floor)GB"
  elif . >= 1048576 then "\(. / 1048576 | floor)MB"
  elif . >= 1024 then "\(. / 1024 | floor)KB"
  else "\(.)B"
  end;
.size | bytes'
# "1GB"

Environment Variables & Arguments

# Access environment variables with $ENV
export MY_VAR="hello"
echo 'null' | jq '$ENV.MY_VAR'
# "hello"

# Access all env vars
echo 'null' | jq '$ENV | keys[:5]'

# --arg: pass string arguments
jq -n --arg name "Alice" --arg age "30" '{name: $name, age: ($age | tonumber)}'
# {"name": "Alice", "age": 30}

# --argjson: pass JSON arguments
jq -n --argjson count 5 --argjson active true '{count: $count, active: $active}'
# {"count": 5, "active": true}

# --slurpfile: read JSON from file into variable
echo '{"name":"Alice"}' > /tmp/user.json
jq -n --slurpfile user /tmp/user.json '$user[0]'
# {"name": "Alice"}

# --slurp (-s): read all inputs into an array
echo -e '{"a":1}\n{"a":2}\n{"a":3}' | jq -s 'map(.a) | add'
# 6

# --null-input (-n): don't read stdin
jq -n '{timestamp: now, message: "hello"}'

# --rawfile: read raw file content as string
jq -n --rawfile tmpl template.txt '$tmpl'

# --jsonargs: pass remaining args as JSON
jq -n '$ARGS.positional' --jsonargs 1 2 3
# [1, 2, 3]

# --join-output / -j: no newline at end
echo '{"name":"Alice"}' | jq -j '.name'
# Alice (no trailing newline)

# --exit-status / -e: set exit code based on output
echo '{"ok":true}' | jq -e '.ok' > /dev/null && echo "success"
# success

12. 速查表:快速参考

最常用的 jq 模式一览。收藏此表以便快速查找。

模式描述示例
.Identity (pretty-print)jq '.'
.fieldGet object fieldjq '.name'
.a.b.cNested field accessjq '.user.address.city'
.[n]Array indexjq '.[0]'
.[]Iterate array/object valuesjq '.users[]'
.[m:n]Array slicejq '.[2:5]'
|Pipe (chain filters)jq '.[] | .name'
select()Filter by conditionjq '.[] | select(.age>30)'
map()Transform array elementsjq 'map(.name)'
sort_by()Sort array by fieldjq 'sort_by(.age)'
group_by()Group by fieldjq 'group_by(.type)'
unique_by()Deduplicate by fieldjq 'unique_by(.id)'
keysGet object keysjq 'keys'
valuesGet object valuesjq 'values'
to_entriesObject to key-value pairsjq 'to_entries'
from_entriesKey-value pairs to objectjq 'from_entries'
with_entries()Transform entries in placejq 'with_entries(.key|=ascii_upcase)'
lengthArray/object/string lengthjq '.items | length'
//Alternative (default value)jq '.x // "default"'
del()Delete key from objectjq 'del(.tmp)'
addSum array / concatjq '[.[] | .score] | add'
flattenFlatten nested arraysjq 'flatten'
@csv / @tsvFormat as CSV/TSVjq -r '.[] | @csv'
@base64Base64 encodejq '.token | @base64'
--arg k vPass string argumentjq --arg n "Alice" '.name==$n'
-rRaw output (no quotes)jq -r '.name'
-sSlurp: read all inputs as arrayjq -s 'add'
-cCompact outputjq -c '.'
-eExit status based on outputjq -e '.ok'
reduceAccumulate valuesjq 'reduce .[] as $x (0;.+$x)'

常见问题

jq 用来做什么?

jq 是一个命令行 JSON 处理器,用于解析、过滤、转换和格式化 JSON 数据。它通常用于处理 API 响应、解析日志文件、转换配置文件以及从复杂 JSON 结构中提取特定字段。可以把它理解为专为 JSON 设计的 grep/sed/awk。

如何用 jq 美化打印 JSON?

只需将 JSON 通过管道传递给 jq 的恒等过滤器:echo '{"name":"Alice","age":30}' | jq '.'。这会输出带有适当缩进和语法高亮的 JSON。也可以用 jq '.' file.json 美化打印 JSON 文件。要使用紧凑输出,添加 -c 标志:jq -c '.' file.json。

如何用 jq 提取嵌套字段?

使用点表示法导航嵌套对象:jq '.user.address.city' data.json。对于数组,使用 .[index] 访问特定元素:jq '.users[0].name' data.json。要遍历所有数组元素,使用 .[]:jq '.users[].name' data.json。可以根据需要无限嵌套。

jq 的 map() 和 select() 有什么区别?

map() 对数组中的每个元素应用转换,返回相同长度的新数组。select() 根据条件过滤元素,只返回匹配的元素。它们经常组合使用:jq '.users | map(select(.age > 30))' 过滤用户数组,只保留年龄大于 30 的用户。map() 负责转换,select() 负责过滤。

如何将 jq 与 curl 配合使用来解析 API 响应?

将 curl 输出直接通过管道传递给 jq:curl -s https://api.github.com/users/octocat | jq '.name, .bio'。-s 标志静音 curl 的进度输出。可以使用任何 jq 过滤器来提取、转换或格式化 API 响应。对于需要认证的 API,添加请求头:curl -s -H "Authorization: Bearer TOKEN" url | jq '.results[]'

收藏这份教程,随时查阅 jq 参考。要在浏览器中处理 JSON 数据,请试试我们的在线工具。

试试 JSON 格式化工具 → | 试试 JSON 查看器 →

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON Formatter🌳JSON Viewer / Tree>>cURL to Code Converter

相关文章

curl 命令速查表:50+ API 测试示例

终极 curl 速查手册,50+ 可复制粘贴的示例。GET、POST、请求头、认证、文件上传、调试。

JSON 格式化与验证:在线美化、修复 JSON 完全指南

免费在线 JSON 格式化和验证工具。美化 JSON、查找语法错误,附 JavaScript 和 Python 代码示例。