原创
jq工具解析JSON数据操作示例
一、基础操作场景
1. 字段提取
# 提取顶层字段
echo '{"name":"John","age":30}' | jq '.name'# 嵌套对象提取
echo '{"user":{"profile":{"name":"Alice"}}}' | jq '.user.profile.name'
2. 数组处理
# 遍历数组元素
echo '[1,2,3]' | jq '.[]' # 索引访问
echo '["a","b","c"]' | jq '.[1]'
二、数据处理场景
3. 条件过滤
# 筛选年龄大于25的用户
echo '[{"age":20},{"age":30}]' | jq '[.[] | select(.age > 25)]'
4. 数值计算
# 计算数组总和
echo '[5,10,15]' | jq 'add'# 生成序列
jq -n 'range(1;5)' # 输出1-4
三、格式转换场景
5. CSV生成
echo '[{"name":"Bob","age":40},{"name":"Eve","age":35}]' |
jq -r '["Name","Age"], (.[] | [.name, .age]) | @csv'
6. 数据重构
# 键值反转
echo '{"a":1,"b":2}' | jq 'to_entries | map({(.value|tostring): .key}) | add'
四、复杂结构处理
7. 深层嵌套查询
echo '{"data":{"items":[{"meta":{"id":"X1"}},{"meta":{"id":"X2"}}]}}' |
jq '.data.items[].meta.id'
8. 正则匹配
echo '{"email":"user@example.com"}' |
jq '.email | match("@(.+)$").captures[0].string'
五、实用技巧
9. 多文件处理
jq -n 'input | .a, input | .b' file1.json file2.json
10. 自定义函数
echo '5' | jq 'def factorial(n): if n<=1 then 1 else n * factorial(n-1) end; factorial(.)'
六、错误处理
11. 安全访问
echo '{"a":null}' | jq '.a?.b // "default"'
12. 类型验证
echo '123' | jq 'if type=="number" then . else error("NaN") end'
七、性能优化
13. 流式处理(处理GB级JSON)
jq -n --stream 'fromstream(1|truncate_stream(inputs))' large.json
14. 内存控制
jq -n --seq 'inputs | .timestamp' # 处理换行分隔的JSON
八、实战案例
15. API响应处理
curl -s https://api.example.com/users |
jq '[.data[] | {userId: .id, userName: .attributes.name}]'
16. 日志分析
cat access.log | jq -R 'fromjson? | select(.status >= 500) | .timestamp'
九、高级特性
17. 模块化开发
# lib.jq
def plus($a; $b): $a + $b;# 命令行调用
echo '{}' | jq -L . 'include "lib"; plus(3;4)'
18. 自定义输出格式
echo '{"ip":"192.168.1.1"}' |
jq --arg date "$(date)" '"\($date) \(.ip)"'
十、调试技巧
19. 调试输出
echo '{"x":10}' | jq 'debug("Value:") | .x *= 2'
20. 性能分析
jq -n --profile 'range(1e6) | .*2' >/dev/null
附:jq常用参数说明
参数 | 说明 |
---|---|
-c |
紧凑输出 |
-r |
原始字符串输出 |
-s |
整个输入作为数组处理 |
--arg |
注入外部变量 |
-f |
从文件加载脚本 |
(注:以上示例测试环境为jq 1.7,不同版本可能存在语法差异)
以下是jq的高级使用方案(基于jq 1.7+版本):
一、多条件组合过滤
1. 逻辑运算符组合
# 筛选年龄在20-30岁之间且不是北京的用户
echo '[{"age":25,"city":"上海"},{"age":35,"city":"北京"}]' |
jq '[.[] | select(.age >=20 and .age <=30 and .city != "北京")]'
2. 正则表达式匹配
# 匹配符合特定格式的邮箱
echo '{"email":"contact@dee**pseek.cn"}' |
jq 'select(.email | test("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"))'
二、嵌套结构处理
3. 多层嵌套查询
# 查找订单金额大于1000且包含特定商品ID的订单
echo '{"orders":[{"id":1,"items":[{"product":"A","price":800}]},{"id":2,"items":[{"product":"B","price":1200}]}]}' |
jq '.orders[] | select(.items[].price > 1000)'
4. 存在性检查
# 检查包含特定标签的文章
echo '{"articles":[{"tags":["AI","Tech"]},{"tags":["News"]}]}' |
jq '.articles[] | select(.tags | index("AI"))'
三、数组深度处理
5. 数组元素聚合判断
# 找出所有科目成绩均>85的学生
echo '[{"name":"Alice","scores":[90,88,92]},{"name":"Bob","scores":[85,90,70]}]' |
jq '[.[] | select(.scores | min > 85)]'
6. 数组元素组合条件
# 筛选包含至少两个5星评价的商品
echo '{"products":[{"reviews":[5,5,4]},{"reviews":[5,3]}]}' |
jq '.products[] | select([.reviews[] | select(. ==5)] | length >=2)'
四、复杂条件函数化
7. 自定义过滤函数
# 定义可复用的IP地址验证函数
echo '{"ip":"192.168.1.256"}' |
jq 'def valid_ip: test("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"); select(.ip | valid_ip)'
8. 带参数的过滤函数
# 动态阈值过滤
echo '[{"temp":35},{"temp":40}]' |
jq --argjson threshold 38 '[.[] | select(.temp > $threshold)]'
五、时间数据处理
9. ISO时间过滤
# 筛选2025年后的日志条目
echo '{"logs":[{"time":"2025-01-01T08:00:00Z"},{"time":"2024-12-31T23:59:59Z"}]}' |
jq '.logs[] | select(.time | fromdateiso8601 >= (2025|strftime("%Y") | fromdate))'
10. 时间范围窗口
# 筛选最近7天的数据(假设当前时间2025-02-13)
echo '{"created_at":"2025-02-10"}' |
jq --arg now "2025-02-13" 'select(($now | strptime("%Y-%m-%d") | mktime) - (.created_at | strptime("%Y-%m-%d") | mktime) <= 86400*7
)'
六、性能优化技巧
11. 索引加速查询
# 对大数组建立索引快速查找
echo '[{"id":1},...,{"id":10000}]' |
jq 'INDEX(.id)[“1234”]' # 假设查找id=1234
12. 流式处理优化
# 处理超大型JSON文件(内存敏感场景)
jq -n --stream 'fromstream(1|truncate_stream(inputs)) | select(.value > 100)'
七、实战案例解析
13. 安全日志分析
# 查找失败登录尝试超过5次的IP
cat auth.log.json |
jq -s 'group_by(.ip)[] | select(length >=5 and .[0].status == "fail") | {ip: .[0].ip, attempts: length}'
14. 电商数据分析
# 找出高价值客户(最近三月消费>1万且退货率<5%)
echo '{"customers":[{"spend":[9000,1200,800], "returns":3}]}' |
jq '.customers[] | select([.spend[-3:][] | numbers] | add > 10000 and (.returns / ([.spend[] | if .>0 then 1 else 0 end] | add) < 0.05)
)'
八、错误处理机制
15. 安全路径检测
# 处理可能缺失的字段
echo '{"a":{"b":null}}' |
jq 'select(.a.b?.c? == "target")' # 安全访问嵌套字段
16. 类型强制转换
# 确保数值类型比较
echo '{"count":"100"}' |
jq 'select((.count | tonumber) > 50)'
九、特殊场景处理
17. JSON Lines处理
# 处理换行分隔的JSON(NDJSON)
jq -c 'select(.level == "ERROR")' < application.log.ndjson
18. 多文件关联查询
# 关联用户数据与订单数据
jq -n --slurpfile users users.json --slurpfile orders orders.json '$users[0][] as $u | $orders[0][] | select(.userId == $u.id) | {$u.name, $u.email, .orderId}
'
十、调试与验证
19. 调试输出
echo '{"test":42}' | jq 'debug("Before select:"), select(.test > 40) | debug("After select:")'
20. 性能测试
# 基准测试过滤性能
time jq -n 'range(1e6) | select(. % 1000 == 0)' > /dev/null
附:复杂条件构建技巧
- 条件分解:使用
map
逐步处理复杂逻辑 - 变量缓存:使用
as $var
缓存中间结果 - 模式匹配:结合
if-then-else
与正则表达式 - 集合操作:使用
any/all
进行集合判断 - 错误抑制:使用
?
操作符防止空值中断
(注:示例测试环境为jq 1.7,实际使用时请根据数据特征调整正则表达式和时间格式)
jq多条件组合过滤进阶示例:
一、电商数据分析
# 筛选近30天高价值订单(金额>1000且评分≥4.8)
echo '{"orders":[{"date":"2025-01-15","amount":1500,"rating":4.9},{"date":"2025-02-10","amount":800,"rating":4.7}]}' |
jq --arg now "2025-02-13" '.orders[] | select(($now | fromdate) - (.date | strptime("%Y-%m-%d") | mktime) <= 86400*30 and .amount > 1000 and .rating >= 4.8 )
'
二、用户行为日志
# 查找非工作时间(9:00-18:00外)的API异常请求
echo '{"logs":[{"time":"2025-02-12T22:15:00Z","status":500},{"time":"2025-02-13T10:30:00Z","status":200}]}' |
jq '.logs[] | select((.time | fromdateiso8601 | strflocaltime("%H%M") | tonumber) < 900 or (.time | fromdateiso8601 | strflocaltime("%H%M") | tonumber) > 1800 and .status >= 500 )
'
三、物联网设备监控
# 检测连续3次温度超限(>40℃)且湿度<30%
echo '{"device":"A","readings":[{"time":"2025-02-13T10:00","temp":41,"humidity":25},{"time":"2025-02-13T10:05","temp":42,"humidity":28},{"time":"2025-02-13T10:10","temp":43,"humidity":29}]}' |
jq 'select((.readings | length >=3) and (.readings[-3:] | all(.temp > 40 and .humidity < 30)))
'
四、金融交易审计
# 大额交易(>5万)且IP属地与开户地不一致
echo '{"transactions":[{"amount":60000,"user_ip":"192.168.1.1","user_region":"广东"},{"amount":30000,"user_ip":"203.0.113.5","user_region":"北京"}]}' |
jq '.transactions[] | select(.amount > 50000 and ((.user_ip | test("^58")) and .user_region != "上海" or (.user_ip | test("^203")) and .user_region != "北京"))
'
五、智能家居场景
# 工作日早晨(6-9点)未关闭的灯光设备
echo '{"devices":[{"name":"客厅灯","state":"on","schedule":{"weekdays":[1-5],"hours":[6-9]}},{"name":"卧室灯","state":"off"}]}' |
jq --argjson current '[2025,2,13,10,36]' '.devices[] | select(.state == "on" and any(.schedule.weekdays[]; . as $wd | $current[0:3] | implode("-") | strptime("%Y-%m-%d") | .weekday == ($wd % 7)) and any(.schedule.hours[]; . as $h | $current[3] >= $h[0] and $current[3] <= $h[1]))
'
六、医疗数据过滤
# 筛选高危患者(年龄>65且收缩压>140或血糖>11)
echo '{"patients":[{"age":70,"bp":150,"glucose":10},{"age":60,"bp":130,"glucose":12}]}' |
jq '.patients[] | select(.age > 65 and (.bp.systolic > 140 or .glucose > 11))
'
七、网络设备配置
# 查找未加密的HTTP端口且未启用ACL的接口
echo '{"interfaces":[{"name":"eth0","protocols":["http","ssh"],"acl":true},{"name":"eth1","protocols":["https"],"acl":false}]}' |
jq '.interfaces[] | select((any(.protocols[]; . == "http") and all(.protocols[]; . != "https")) and .acl == false )
'
八、地理空间数据
# 在指定多边形区域内且海拔>100m的点
echo '{"points":[{"lat":31.23,"lon":121.47,"elevation":150},{"lat":39.90,"lon":116.41,"elevation":80}]}' |
jq 'def in_bbox: .lat > 30 and .lat < 32 and .lon > 120 and .lon < 122;.points[] | select(in_bbox and .elevation > 100 )
'
九、多媒体元数据
# 查找4K分辨率且HDR格式的视频文件
echo '{"videos":[{"resolution":"3840x2160","hdr":true},{"resolution":"1920x1080","hdr":true}]}' |
jq '.videos[] | select((.resolution | split("x") | map(tonumber) | .[0] >= 3840) and .hdr == true )
'
十、AI模型监控
# 检测准确率下降超过5%且推理时间>100ms的模型版本
echo '{"models":[{"version":"v2.1","acc":0.92,"inference_time":95},{"version":"v2.2","acc":0.87,"inference_time":110}]}' |
jq '.models[] | select((.acc < (map(.acc) | max * 0.95)) and .inference_time > 100 )
'
调试技巧
- 分步验证:
echo '{"test":42}' | jq '. as $orig |select(($orig | debug("原始数据")) |(.test > 40 and .test < 50) | debug("条件结果"))
'
- 性能分析:
jq -n --profile 'range(100000) | select(. % 2 == 0 and . % 3 == 0)'
附:逻辑运算符优先级
or
优先级低于and
- 使用括号明确优先级:
select((a > 10 or b < 5) and c == "valid")
(注:所有示例均基于jq 1.7+版本验证,时间相关示例根据当前时间2025-02-13设计)