1. 命令概述
- 命令名称:
jq(JSON Query) - 核心功能:JSON数据处理工具,用于解析、过滤、转换和格式化JSON数据
- 主要用途:JSON数据查询、数据提取、格式转换、数据验证
- 特点:轻量级、功能强大、支持管道操作、跨平台
2. 语法格式
jq [选项] '过滤器' [文件...]
3. 常用选项
| 选项 | 说明 |
|---|---|
-c | 紧凑输出(每行一个JSON对象) |
-r | 输出原始字符串(不转义) |
-s | 将输入流作为数组读取 |
-M | 单色输出(不显示颜色) |
-S | 按键名排序输出 |
-n | 使用null作为输入 |
--help | 显示帮助信息 |
--version | 显示版本信息 |
4. 基本操作
(1) 基本查询
# 提取所有字段
jq '.' data.json
# 提取指定字段
jq '.name' data.json
# 提取嵌套字段
jq '.user.name' data.json
# 提取数组元素
jq '.users[0]' data.json
# 提取数组所有元素
jq '.users[]' data.json
# 提取多个字段
jq '.name, .age' data.json
(2) 条件过滤
# 条件查询
jq 'select(.age > 18)' data.json
# 多条件查询
jq 'select(.age > 18 and .city == "Beijing")' data.json
# 正则匹配
jq 'select(.email | test("@gmail.com"))' data.json
# 包含判断
jq 'select(.tags | contains(["linux"]))' data.json
(3) 数据转换
# 创建新对象
jq '{name: .name, age: .age}' data.json
# 添加字段
jq '. + {country: "China"}' data.json
# 删除字段
jq 'del(.email)' data.json
# 重命名字段
jq '. + {fullName: .name} | del(.name)' data.json
# 数组操作
jq '.users | map({name: .name, age: .age})' data.json
(4) 格式化输出
# 紧凑输出
jq -c '.' data.json
# 原始字符串输出
jq -r '.name' data.json
# 排序输出
jq -S '.' data.json
# 单色输出
jq -M '.' data.json
# 数组流处理
jq -s '.' data.json
5. 常用实例详解
(1) 基本查询示例
假设文件 data.json内容为:
{
"name": "Alice",
"age": 25,
"city": "Beijing",
"email": "alice@example.com",
"hobbies": ["reading", "music", "travel"],
"address": {
"street": "123 Main St",
"zipcode": "100000"
}
}
# 提取所有字段
jq '.' data.json
# 提取name字段
jq '.name' data.json # 输出:"Alice"
# 提取嵌套字段
jq '.address.street' data.json # 输出:"123 Main St"
# 提取数组元素
jq '.hobbies[0]' data.json # 输出:"reading"
# 提取数组所有元素
jq '.hobbies[]' data.json # 输出:"reading" "music" "travel"
# 提取多个字段
jq '.name, .age' data.json # 输出:"Alice" 25
(2) 条件过滤示例
# 条件查询
jq 'select(.age > 20)' data.json
# 多条件查询
jq 'select(.age > 20 and .city == "Beijing")' data.json
# 正则匹配
jq 'select(.email | test("@example.com"))' data.json
# 包含判断
jq 'select(.hobbies | contains(["music"]))' data.json
# 长度判断
jq 'select(.hobbies | length > 2)' data.json
# 空值判断
jq 'select(.email != null)' data.json
(3) 数据转换示例
# 创建新对象
jq '{name: .name, age: .age}' data.json
# 输出:{"name": "Alice", "age": 25}
# 添加字段
jq '. + {country: "China"}' data.json
# 输出:{..., "country": "China"}
# 删除字段
jq 'del(.email)' data.json
# 输出:删除email字段
# 重命名字段
jq '. + {fullName: .name} | del(.name)' data.json
# 输出:{"fullName": "Alice", ...}
# 数组操作
jq '.hobbies | map({hobby: .})' data.json
# 输出:[{"hobby": "reading"}, {"hobby": "music"}, {"hobby": "travel"}]
# 数组展开
jq '.hobbies | .[]' data.json
# 输出:"reading" "music" "travel"
# 数组过滤
jq '.hobbies | map(select(length > 5))' data.json
# 输出:["reading", "travel"]
(4) 格式化输出示例
# 紧凑输出
jq -c '.' data.json
# 输出:{"name":"Alice","age":25,...}
# 原始字符串输出
jq -r '.name' data.json
# 输出:Alice(不带引号)
# 排序输出
jq -S '.' data.json
# 输出:按键名排序
# 单色输出
jq -M '.' data.json
# 输出:不显示颜色
# 数组流处理
jq -s '.' data.json
# 输出:将输入作为数组处理
6. 实际应用场景
场景一:API响应处理
# 提取API响应中的特定字段
curl -s https://api.example.com/users | jq '.data[] | {id: .id, name: .name}'
# 过滤API响应
curl -s https://api.example.com/users | jq 'select(.status == "active")'
# 统计API响应数量
curl -s https://api.example.com/users | jq '.data | length'
# 格式化API响应
curl -s https://api.example.com/users | jq -c '.data[]'
# 提取嵌套数据
curl -s https://api.example.com/users | jq '.data[].profile.email'
场景二:配置文件处理
# 提取配置文件中的值
jq '.database.host' config.json
# 修改配置文件
jq '.database.host = "localhost"' config.json > config_new.json
# 添加配置项
jq '. + {debug: true}' config.json > config_new.json
# 删除配置项
jq 'del(.database.password)' config.json > config_new.json
# 合并配置文件
jq -s '.[0] * .[1]' config1.json config2.json > merged.json
场景三:日志分析
# 提取日志中的错误信息
jq 'select(.level == "ERROR")' app.log
# 统计错误数量
jq 'select(.level == "ERROR") | length' app.log
# 按时间分组统计
jq 'group_by(.timestamp | split(" ")[0]) | map({date: .[0].timestamp | split(" ")[0], count: length})' app.log
# 提取IP地址
jq '.ip' access.log | sort | uniq -c
# 统计状态码
jq '.status' access.log | sort | uniq -c
场景四:数据转换
# JSON转CSV
jq -r '["name", "age", "city"], (.users[] | [.name, .age, .city]) | @csv' data.json
# JSON转TSV
jq -r '["name", "age", "city"], (.users[] | [.name, .age, .city]) | @tsv' data.json
# JSON转表格
jq -r '["name", "age", "city"], (.users[] | [.name, .age, .city]) | join("\t")' data.json
# JSON转XML
jq -r '.users[] | "<user><name>\(.name)</name><age>\(.age)</age></user>"' data.json
# JSON转YAML
jq -r '.users[] | "name: \(.name)\nage: \(.age)"' data.json
7. 与其他命令的区别
| 命令 | 特点 | 适用场景 |
|---|---|---|
jq | JSON数据处理工具 | JSON查询、过滤、转换 |
grep | 文本搜索工具 | 模式匹配、搜索 |
awk | 文本处理工具 | 复杂文本处理、报表生成 |
sed | 流编辑器 | 文本替换、删除 |
curl | 网络传输工具 | API调用、数据获取 |
8. 注意事项
- 输入格式:输入必须是有效的JSON格式
- 输出格式:默认输出格式化JSON,使用
-r输出原始字符串 - 错误处理:遇到错误会返回非零退出码
- 性能:处理大文件时性能较好
- 兼容性:支持大部分JSON标准特性
9. 常见问题解决
(1) 输入格式问题
# 错误:输入不是JSON格式
echo "invalid json" | jq '.' # 报错
# 正确:使用JSON格式
echo '{"name": "Alice"}' | jq '.'
# 处理非标准JSON
curl -s https://api.example.com/data | jq -r '.data'
# 处理空输入
echo "" | jq '.' # 输出:null
# 处理数组输入
echo '[1,2,3]' | jq '.[]'
(2) 输出格式问题
# 输出原始字符串
jq -r '.name' data.json
# 输出紧凑格式
jq -c '.' data.json
# 输出排序格式
jq -S '.' data.json
# 输出单色格式
jq -M '.' data.json
# 输出数组格式
jq -s '.' data.json
(3) 复杂查询问题
# 嵌套查询
jq '.users[] | select(.age > 18) | {name: .name, age: .age}' data.json
# 数组操作
jq '.users | map({name: .name, age: .age}) | sort_by(.age)' data.json
# 分组统计
jq '.users | group_by(.city) | map({city: .[0].city, count: length})' data.json
# 条件赋值
jq '.users[] | if .age > 18 then . + {adult: true} else . + {adult: false} end' data.json
# 正则替换
jq '.users[] | .email |= sub("@.*"; "@example.com")' data.json
(4) 性能优化
# 使用管道操作
jq '.users[] | select(.age > 18)' data.json
# 使用数组操作
jq '.users | map(select(.age > 18))' data.json
# 使用流处理
jq -c '.users[]' data.json | jq 'select(.age > 18)'
# 使用临时文件
jq '.' data.json > temp.json
jq '.name' temp.json
# 使用内存映射
jq -n 'reduce inputs as $item (.; . += $item)' data.json
核心要点总结:
jq是功能强大的JSON数据处理工具,支持查询、过滤、转换和格式化- 常用选项:
-c(紧凑输出)、-r(原始字符串输出)、-s(数组流处理)、-S(排序输出) - 实际应用:API响应处理、配置文件处理、日志分析、数据转换
- 注意事项:输入必须是有效的JSON格式,支持管道操作,处理大文件性能较好
jq命令是处理JSON数据的必备工具,熟练掌握可以大大提高数据处理效率。