jq:命令行里的 JSON 处理利器
JSON 已经成为接口交互和配置文件的主流格式。不管是运维还是开发,每天都要面对 curl 吐回来的接口返回、日志里的 JSON 字段、Kubernetes 的资源描述……靠 grep 硬抠迟早翻车。jq 就是专为命令行处理 JSON 而生的工具,轻量、单文件、无依赖,装上之后很多脏活累活都变得优雅。
一、安装与最小示例
主流发行版基本都能一键安装:
# Ubuntu / Debian
sudo apt install jq
# CentOS / RHEL
sudo yum install jq
# macOS
brew install jq
jq 的工作流很简单:读入 JSON → 用过滤器(filter)变换 → 输出结果。. 表示整个输入:
echo '{"name":"ecs-01","status":"running","cpu":4}' | jq .
加上 . 会把 JSON 格式化输出,这是最常用的“美化打印”姿势,排查接口返回时几乎人手必备:
curl -s https://api.example.com/servers | jq .
二、取字段:点语法就够了
取嵌套字段直接用点连接:
echo '{"server":{"name":"ecs-01","ip":"192.168.1.10"}}' | jq .server.name
# "ecs-01"
echo '{"server":{"name":"ecs-01","ip":"192.168.1.10"}}' | jq .server.ip
# "192.168.1.10"
数组用下标,[] 则展开数组里的每个元素:
echo '[{"name":"a"},{"name":"b"}]' | jq .[0].name # "a"
echo '[{"name":"a"},{"name":"b"}]' | jq .[].name # "a" "b"
输出默认带引号,写脚本想拿裸字符串时加 -r(raw output):
echo '{"ip":"192.168.1.10"}' | jq -r .ip
# 192.168.1.10
一次取多个字段拼成新对象也很方便:
echo '{"name":"ecs-01","ip":"192.168.1.10","cpu":4}' | jq '{name, ip}'
# {"name":"ecs-01","ip":"192.168.1.10"}
三、管道与组合:把 jq 当流水线用
jq 里的 | 和 shell 管道思想一致,把上一步的结果喂给下一步:
# 从实例列表里取出所有 running 状态主机的内网 IP
curl -s https://api.example.com/servers | jq -r '.servers[] | select(.status=="running") | .private_ip'
几个高频组合函数:
select(条件):过滤元素,相当于 SQL 里的 wheremap(表达式):对数组每个元素做变换sort_by(字段):按字段排序length:数组长度或字符串长度keys:取对象的所有键名
echo '{"a":1,"b":2,"c":3}' | jq keys # ["a","b","c"]
echo '[1,2,3,4]' | jq 'map(. * 2)' # [2,4,6,8]
echo '[{"n":"b"},{"n":"a"}]' | jq 'sort_by(.n)' # 按 n 排序
四、实战:从日志和 API 里捞数据
场景一:Nginx 日志按 JSON 格式输出后,统计各状态码数量:
jq -s 'group_by(.status) | map({status: .[0].status, count: length}) | sort_by(.count) | reverse' access.json
场景二:把 Pod 列表整理成“名字 + IP”的表格:
kubectl get pods -o json | jq -r '.items[] | "\(.metadata.name)\t\(.status.podIP)"'
场景三:构造请求体。jq 不只能读,还能用 --arg 把 shell 变量安全地拼进 JSON,再也不用手写引号转义:
NAME="ecs-02"
jq -n --arg name "$NAME" '{server: {name: $name, image: "ubuntu-22.04"}}'
# {
# "server": {
# "name": "ecs-02",
# "image": "ubuntu-22.04"
# }
# }
五、几个容易踩的坑
- 过滤器用单引号包裹:过滤器里有
$、|或空格时务必用单引号,否则会被 shell 先解释。 - 大整数精度:jq 内部用双精度浮点数表示数字,超大整数(如雪花 ID)会被截断,取用时尽量当字符串处理。
-c紧凑输出:默认格式化输出适合人看;给下游程序消费时加-c输出单行,配合 xargs 更顺手。- 空值兜底:字段可能缺失时用
//给默认值,例如jq -r '.nickname // "匿名"',脚本更健壮。
结语
jq 的学习曲线很平缓:先记住 .、[]、-r、select 这几个,日常八成的 JSON 处理需求就覆盖了。剩下的高级函数(reduce、walk、@csv 等)等真正遇到再查手册也不迟。把它装进你的工具箱,下次再面对几兆的接口返回,就不用靠肉眼 grep 了。
- 点赞
- 收藏
- 关注作者
评论(0)