暗色模式

jq 命令行:从 JSON 格式化到字段取值与 API 调试

技术教程
2026-08-20
6
0
本文要点
  • jq 三层功能一学就会:格式化实时 JSON、按路径取字段、管道拼接做过滤/排序/求和,是 curl 调试 API 的黄金搭档;
  • jq . 让乱成一团的 JSON 秒变缩进清晰的层级结构,配 -c 还能反向压成单行;
  • 字段取值用 .servers[].name 一路点下去,-r 去掉引号输出纯文本,keyslength 看结构看数量;
  • select(.status == "running") 按条件筛行,sort_by(.cpu) 排序,add 求和,字符串拼接能制表;
  • 最实用场景:curl -s url | jq '...' 直接在终端把 API 返回的 JSON 抽出我们想要的字段,不必再手动找。

为什么需要 jq

打开一个真实 API 接口,返回的 JSON 往往是几百行、层层嵌套、挤在一团里。我们用眼睛很难直接从里面找出「核心限制还剩几次」「哪台机器还活着」,更别说在脚本里自动处理了。

jq 就是干这个的——它是一个命令行下的 JSON 处理器,能帮你完成三件事:

  1. :把乱成麻绳的 JSON 排版成清晰的层级结构;
  2. :按路径把某个字段的值抽出来;
  3. :像管道一样把多个步骤串起来,做过滤、排序、求和、制表。

它和文本三剑客里的 grep/sed/awk 定位不同:那三位处理的是任意文本,而 jq 天生理解 JSON 结构,所以处理配置文件、云厂商 API 返回、日志里的 JSON 行时,比正则匹配清爽得多。它在绝大多数 Linux 发行版仓库里都有,安装只需要一条命令:

# Debian/Ubuntu
apt install -y jq

# CentOS/RHEL
yum install -y jq

方便起见,下面所有例子都用同一个小型「服务器清单」JSON 来演示,你可以照抄到自己的环境里跟着做:

{
  "servers": [
    {"name": "web01", "region": "cn-hongkong", "ip": "47.238.230.124", "status": "running", "cpu": 8, "uptime_days": 120},
    {"name": "db01", "region": "cn-shanghai", "ip": "47.100.85.66", "status": "running", "cpu": 16, "uptime_days": 320},
    {"name": "cache01", "region": "ap-singapore", "ip": "13.212.77.9", "status": "stopped", "cpu": 2, "uptime_days": 0},
    {"name": "backup01", "region": "cn-hangzhou", "ip": "121.40.50.8", "status": "running", "cpu": 4, "uptime_days": 200}
  ],
  "owner": "Astarry",
  "total": 4
}

格式化:让 JSON 变得可读

先看它最基础也最高频的用途——看懂一份 JSON。任何 JSON 输入,只要丢给 jq . 就会从「一行挤到底」变成「按缩进排好」:

echo '{"a":1,"b":[1,2]}' | jq

不带表达式时 jq 默认执行 .(取整个输入),并把结果按层级美化输出:

{
  "a": 1,
  "b": [
    1,
    2
  ]
}

反过来,想让 JSON 变成单行、方便写进日志或传给下一个命令,用 -c(compact):

echo '{"a":1,"b":[1,2]}' | jq -c
# 输出: {"a":1,"b":[1,2]}

对一份较大的清单文件,jq keys 能一眼列出顶层有哪些键,帮你快速摸清结构;jq '.servers | length' 则直接告诉你数组里有多少元素:

jq keys /tmp/servers.json
jq -r .owner /tmp/servers.json
jq '.servers | length' /tmp/servers.json

输出依次是顶层键 ownerserverstotal,取到的 ownerAstarry,以及服务器总数 4

jq 基础:keys 字段枚举与 length 数组长度

取值:点号一路点进去

jq 的核心语法就是点号路径,跟 JS 里访问对象几乎一样。取 owner 字段就是 .owner,取服务器数组第二个元素就是 .servers[1],再取它的名字就是 .servers[1].name

默认情况下 jq 输出的是带引号的 JSON 字符串"web01")。在脚本里要想拿到纯文本,加 -r(raw)去引号:

jq -r '.owner' /tmp/servers.json   # 输出 Astarry,不带引号

[] 是所有数组元素的意思,配合点号可以"横着扫"整批对象。例如取所有服务器的名字:

jq -r '.servers[].name' /tmp/servers.json
# web01
# db01
# cache01
# backup01

取字段还能计算:想统计所有服务器 CPU 核数之和,先把 .servers[].cpu 收集进数组(外层加 []),再用 add 求和:

jq '[.servers[].cpu] | add' /tmp/servers.json   # 输出 30

过滤与排序:条件筛选出想要的行

.servers[] 会吐出所有服务器,可很多时候我们只关心满足条件的那几台——比如「还跑着的机器」。这要用 select(条件)

jq '.servers[] | select(.status == "running") | .name' /tmp/servers.json

它会像 grep 那样把数组过滤一遍,只留下 statusrunning 的元素,再取它们的名字,得到 web01db01backup01cache01 已被排除)。

排序用 sort_by,比如按 CPU 核数从低到高排列,并只留下 namecpu 两个字段重新构造成小对象:

jq -c '.servers | sort_by(.cpu) | .[] | {name, cpu}' /tmp/servers.json
# {"name":"cache01","cpu":2}
# {"name":"backup01","cpu":4}
# {"name":"web01","cpu":8}
# {"name":"db01","cpu":16}

如果你只想从数组里挑出一个元素,比如取第一台机器然后重组字段名,可以这样写:

jq '.servers[0] | {host: .name, cores: .cpu}' /tmp/servers.json
# { "host": "web01", "cores": 8 }

上面这些过滤、排序、重组、求和的组合用法:

jq 排序与重组:sort_by、对象构造与求和

字符串拼接:把 JSON 变表格

jq 支持用 \() 把字段值插进字符串,用 \t 表示制表符,于是很轻松就能把结构化 JSON 变成一格一格的表格——这在"把 API 结果汇总打印给人看"时格外好用:

jq -r '.servers[] | "\(.name)\t\(.status)\t\(.cpu)\t\(.region)"' /tmp/servers.json

输出不再是 JSON,而是对齐的文本表格:

web01    running    8    cn-hongkong
db01    running    16    cn-shanghai
cache01    stopped    2    ap-singapore
backup01    running    4    cn-hangzhou

把过滤和拼接组合起来,就得到一张"只包含在跑机器"的清单:

jq -r '.servers[] | select(.status == "running") | "\(.name)\t\(.status)\t\(.cpu)"' /tmp/servers.json

过滤 + 字符串拼接成表的示例:

jq 过滤与制表:select 条件与字符串拼接

实战:curl + jq 解析 API 响应

jq 最常见的使用场景,是接在 curl 后面直接解析返回的 JSONcurl -s 去静默地拉 API 数据,| 交给 jq(jq 会读标准输入),jq 再只抽出我们想要的字段。一条命令搞定,不用把 JSON 存下来再人工翻找。

以 GitHub 的限流接口为例,它返回当前每小时剩余请求次数:

curl -s 'https://api.github.com/rate_limit' | jq -r '.resources.core.limit, .resources.core.remaining'

直接在终端看到两个数字(比如都是 60,即上限 60、还剩 60),写巡检脚本时想判断"剩余次数会不会掉到 0",抓这个值就对了:

curl + jq:解析 API 返回的经典组合

类似的思路可以套在任何返回 JSON 的接口上——查云服务器状态、查天气、查快递、查区块链价格,都是 curl -s url | jq '要的路径'。配合我们之前讲过的 《curl 命令行:从文件下载到 HTTP 接口调试》,这一套足以应对绝大多数"命令行里顺手调接口"的需求。

小结

  • jq . 负责把 JSON 排版成可读结构,-c 反向压成单行,keys/length 快速摸清结构;
  • 点号路径 .servers[].name 按路径取值,-r 去掉引号拿纯文本,[.x] | add 能求和;
  • select(条件) 过滤行、sort_by 排序、\() 字符串插值,能把 JSON 变成给人看的表格;
  • 最高频组合是 curl -s url | jq '...'——在终端直接抽出 API 返回里的关键字段;
  • jq 理解 JSON 结构,比用正则硬拆可靠得多,是运维脚本里处理接口返回的不二之选。

发表评论

暂无评论,快来抢沙发吧!