JSON / jq 开发配置速查表
本速查表覆盖 jq 命令行 JSON 处理工具的常用操作,包括键值访问、数组过滤、对象操作、管道链式处理及内置函数,帮助你在 Shell 脚本中高效处理 JSON 数据。
基本操作 (jq-basic)
``bash
# 格式化 JSON
cat data.json | jq '.'
# 提取根键 cat data.json | jq '.name'
# 提取嵌套键 cat data.json | jq '.address.city'
# 可选操作符(键不存在时不报错) cat data.json | jq '.name?'
# 提取多个键 cat data.json | jq '{name, email}'
# 逗号运算符(多个表达式) cat data.json | jq '.name, .age'
# 管道给另一个 jq cat data.json | jq '.users' | jq '.[]'
# 原始输出(去掉引号) cat data.json | jq -r '.name'
# 紧凑输出(去掉换行和缩进) cat data.json | jq -c '.'
# 从标准输入读取
echo '{"a": 1}' | jq '.a'
`
过滤操作 (jq-filter)
`bash
# 数组展开
cat data.json | jq '.users[]'
# 条件选择 cat data.json | jq '.users[] | select(.age > 18)'
# 多条件 AND cat data.json | jq '.users[] | select(.age > 18 and .city == "Beijing")'
# 多条件 OR cat data.json | jq '.users[] | select(.age > 60 or .role == "admin")'
# 反向选择 cat data.json | jq '.users[] | select(.age < 18 | not)'
# 包含判断 cat data.json | jq '.users[] | select(.tags | index("vip"))'
# 自定义函数过滤 cat data.json | jq '[.[] | select(.price > 10 and .price < 100)]'
# 空值/非空过滤 cat data.json | jq '.users[] | select(.email != null)'
# 字符串匹配 cat data.json | jq '.users[] | select(.name | test("^A.*"))'
# 正则测试
cat data.json | jq '.users[] | select(.phone | test("^1[3-9]\\d{9}$"))'
`
数组操作 (jq-array)
`bash
# 数组长度
cat data.json | jq '.users | length'
# 取第一个/最后一个元素 cat data.json | jq '.users[0]' cat data.json | jq '.users[-1]'
# 数组切片 cat data.json | jq '.users[0:3]' # 前3个 cat data.json | jq '.users[2:5]' # 第3-5个 cat data.json | jq '.users[:2]' # 前2个
# 数组扁平化 cat data.json | jq '[.. | objects | .name?]'
# 数组去重 cat data.json | jq '[.users[].city] | unique'
# 排序 cat data.json | jq '.users | sort_by(.age)'
# 反向排序 cat data.json | jq '.users | sort_by(.age) | reverse'
# 数组添加元素 cat data.json | jq '.users + [{name: "New"}]'
# 最小/最大值 cat data.json | jq '[.users[].age] | min' cat data.json | jq '[.users[].age] | max'
# 数组映射
cat data.json | jq '[.users[] | {name, age, adult: (.age >= 18)}]'
`
对象操作 (jq-object)
`bash
# 选取部分字段
cat data.json | jq '.users[] | {name, email}'
# 重命名字段 cat data.json | jq '.users[] | {user_name: .name, user_age: .age}'
# 添加字段 cat data.json | jq '.users[] | . + {active: true}'
# 删除字段 cat data.json | jq 'del(.users[].password)'
# 合并对象 cat data.json | jq '.user1 * .user2'
# 键值对转对象 cat data.json | jq '.users | from_entries'
# 对象转键值对 cat data.json | jq '.users | to_entries'
# 获取所有键 cat data.json | jq '.users[0] | keys'
# 检查键是否存在 cat data.json | jq '.users[0] | has("email")'
# 获取键值对 cat data.json | jq '.users[0] | to_entries[] | "\(.key): \(.value)"'
# 仅保留非空字段
cat data.json | jq '.users[] | with_entries(select(.value != null))'
`
管道与组合 (jq-pipe)
`bash
# 链式管道
cat data.json | jq '.users | sort_by(.age) | reverse | .[0:3]'
# 分组 cat data.json | jq '.users | group_by(.city)'
# 分组后统计 cat data.json | jq '.users | group_by(.city) | map({city: .[0].city, count: length})'
# 分组后聚合 cat data.json | jq '.users | group_by(.city) | map({city: .[0].city, total_age: map(.age) | add})'
# slurp 模式(将多行 JSON 读为数组) cat data.json | jq -s '. | length'
# slurp 后处理 cat data.json | jq -s 'group_by(.type) | map({type: .[0].type, count: length})'
# 使用 --arg 传递 Shell 变量 city="Beijing" cat data.json | jq --arg city "$city" '.users[] | select(.city == $city)'
# 使用 --argjson 传递 JSON 值 cat data.json | jq --argjson min 18 '.users[] | select(.age >= $min)'
# 使用 --rawfile 读取文件内容 cat data.json | jq --rawfile tmpl template.txt '.message = $tmpl'
# 定义函数
cat data.json | jq 'def double: . * 2; [.users[].age | double]'
`
内置函数 (jq-builtin)
`bash
# length - 字符串/数组/对象长度
cat data.json | jq '.name | length'
cat data.json | jq '.users | length'
# keys - 对象键列表 cat data.json | jq 'keys'
# has - 检查键是否存在 cat data.json | jq 'has("users")'
# select - 条件过滤 cat data.json | jq '.users[] | select(.age > 18)'
# map - 映射 cat data.json | jq '[.users[] | map(.name)]'
# add - 数组求和 cat data.json | jq '[.users[].age] | add'
# join - 数组拼接为字符串 cat data.json | jq '[.users[].name] | join(", ")'
# split - 字符串分割 cat data.json | jq -r '.names | split(", ")'
# unique - 数组去重并排序 cat data.json | jq '[.users[].city] | unique'
# sort - 排序 cat data.json | jq '[.users[].age] | sort'
# range - 生成数字序列 cat data.json | jq '[range(5)]'
# floor / sqrt cat data.json | jq '[.users[].score | floor]' cat data.json | jq '[.users[].score | sqrt]'
# tostring / tonumber cat data.json | jq '.users[].age | tostring' echo '"42"' | jq 'tonumber'
# type - 返回类型名称 cat data.json | jq '.users | type'
# null 判断 cat data.json | jq '.missing // "default_value"'
# empty - 返回空(用于过滤) cat data.json | jq '.users[] | select(.age > 100) | (.name, empty)'
# error - 抛出错误
cat data.json | jq 'if .users == null then error("no users") else . end'
`
jq 命令行选项
`bash
# 常用选项速查
jq '.' data.json # 格式化文件
jq -c '.' data.json # 紧凑输出
jq -r '.name' data.json # 原始输出(无引号)
jq -n '{"a": 1}' # 从头创建 JSON(无输入)
jq -s '.' *.json # slurp 模式:合并多个文件
jq --arg k v '.[$k]' # 传参
jq --argjson k 42 '.[$k]' # 传 JSON 参数
jq -f script.jq data.json # 从文件读取过滤器
``
基本操作(8)
| 命令 | 难度 | ||
|---|---|---|---|
jq '.' data.json格式化输出 JSON | 基础 | jq '.' data.json | |
jq '.address.city'提取嵌套键值 | 基础 | cat data.json | jq '.address.city' | |
jq '.name?'可选操作符,键不存在不报错 | 基础 | cat data.json | jq '.name?' | |
jq '{name, email}'提取多个键 | 基础 | cat data.json | jq '{name, email}' | |
jq '.name, .age'逗号运算符(多个表达式分别求值) | 中级 | cat data.json | jq '.name, .age' | |
jq -r '.name'原始输出(去掉字符串引号) | 基础 | cat data.json | jq -r '.name' | |
jq -c '.'紧凑输出(单行,无缩进) | 基础 | cat data.json | jq -c '.' | |
jq -f script.jq data.json从文件读取 jq 过滤器 | 中级 | jq -f script.jq data.json |
过滤(5)
| 命令 | 难度 | ||
|---|---|---|---|
jq '.users[]'展开数组为多个元素 | 基础 | cat data.json | jq '.users[]' | |
jq '.users[] | select(.age > 18)'条件过滤数组元素 | 中级 | cat data.json | jq '.users[] | select(.age > 18)' | |
jq '.users[] | select(.age > 18 and .city == "Beijing")'多条件 AND 过滤 | 中级 | cat data.json | jq '.users[] | select(.age > 18 and .city == "Beijing")' | |
jq '.users[] | select(.age > 60 or .role == "admin")'多条件 OR 过滤 | 中级 | cat data.json | jq '.users[] | select(.age > 60 or .role == "admin")' | |
jq '.users[] | select(.name | test("^A.*"))'正则匹配过滤 | 高级 | cat data.json | jq '.users[] | select(.name | test("^A.*"))' |
数组(6)
| 命令 | 难度 | ||
|---|---|---|---|
jq '.users | length'获取数组长度 | 基础 | cat data.json | jq '.users | length' | |
jq '.users[0]'取数组第一个元素 | 基础 | cat data.json | jq '.users[0]' | |
jq '.users[-1]'取数组最后一个元素 | 基础 | cat data.json | jq '.users[-1]' | |
jq '.users[0:3]'数组切片(取前3个) | 中级 | cat data.json | jq '.users[0:3]' | |
jq '.users | sort_by(.age)'按字段排序 | 中级 | cat data.json | jq '.users | sort_by(.age)' | |
jq '[.users[].city] | unique'数组去重并排序 | 中级 | cat data.json | jq '[.users[].city] | unique' |
对象(6)
| 命令 | 难度 | ||
|---|---|---|---|
jq '.users[] | {name, email}'选取对象的指定字段 | 基础 | cat data.json | jq '.users[] | {name, email}' | |
jq '.users[] | {user_name: .name, user_age: .age}'重命名对象字段 | 中级 | cat data.json | jq '.users[] | {user_name: .name, user_age: .age}' | |
jq '.users[] | . + {active: true}'向对象添加字段 | 中级 | cat data.json | jq '.users[] | . + {active: true}' | |
jq 'del(.users[].password)'删除对象字段 | 中级 | cat data.json | jq 'del(.users[].password)' | |
jq '.users[0] | keys'获取对象的所有键 | 基础 | cat data.json | jq '.users[0] | keys' | |
jq '.users[0] | has("email")'检查键是否存在 | 基础 | cat data.json | jq '.users[0] | has("email")' |
管道(4)
| 命令 | 难度 | ||
|---|---|---|---|
jq -s '.'使用 slurp 模式将多行/多文件 JSON 读为数组 | 中级 | cat data.json | jq -s '.' | |
jq --arg city "Beijing" '.users[] | select(.city == $city)'通过 --arg 传递 Shell 变量到 jq | 中级 | jq --arg city "Beijing" '.users[] | select(.city == $city)' | |
jq --argjson min 18 '.users[] | select(.age >= $min)'通过 --argjson 传递 JSON 值 | 高级 | jq --argjson min 18 '.users[] | select(.age >= $min)' | |
jq '.users | group_by(.city)'按字段分组 | 高级 | cat data.json | jq '.users | group_by(.city)' |
内置函数(4)
| 命令 | 难度 | ||
|---|---|---|---|
jq '[.users[].name] | join(", ")'join 函数:数组拼接为字符串 | 中级 | cat data.json | jq '[.users[].name] | join(", ")' | |
jq '[.users[].age] | add'add 函数:数组求和 | 中级 | cat data.json | jq '[.users[].age] | add' | |
jq '.missing // "default"'空值合并运算符,字段缺失时使用默认值 | 中级 | cat data.json | jq '.missing // "default"' | |
jq -n '{"a": 1}'不依赖输入,从头创建 JSON(-n) | 基础 | jq -n '{"a": 1}' |