jq 是什么
jq 是命令行里的 JSON 处理器:点号取字段、方括号取数组元素、管道串联多个步骤,再加 select、map 这类函数做过滤与变形。它把结构化数据从「一堆文本」还原成可精确寻址的对象,比用 cut、awk 按位置切字符串稳得多。接口调试、云平台命令行输出提取、日志里的 JSON 字段分析,都靠它。
基本信息
| 适用平台 | Linux、macOS、Windows 均可安装,发行版仓库里通常有 jq 包 |
|---|---|
| 命令语法 | jq [选项] 过滤器 [文件...] |
| 常用选项 | -r 输出裸字符串 / -c 紧凑单行 / -e 按结果给退出码 / -n 不读输入 / -s 把输入读成数组 / --arg 传入变量 |
| 核心过滤器 | . 原样、.a.b 路径取值、.[] 遍历数组、select 过滤、map 映射、length 长度、keys 键列表 |
典型使用场景
- 接口调试:把一行 JSON 展开成缩进格式,看清结构
- 字段提取:从云平台命令行的输出里取 id、地址之类的值
- 条件筛选:只保留状态为 active 的条目
- 改写配置:对 JSON 配置做增量修改再写回
- 日志分析:把每行 JSON 日志抽成需要的列
常用示例
常用示例
curl -s https://api.example.com/status | jq .
curl -s https://api.example.com/status | jq -r '.data.host'
jq -r '.items[] | select(.status=="active") | .name' data.json
jq -c '{name, port}' conf.json > tmp.json && mv tmp.json conf.json
jq '.port = 8080' conf.json | sponge conf.json # 就地修改,需 moreutils
jq -r --arg env prod '.services[] | select(.env==$env) | .name' cfg.json常用过滤器
| 过滤器 | 作用 | 示例 |
|---|---|---|
| . | 原样输出并格式化 | jq . |
| .a.b | 按键路径取值 | jq .data.host |
| . [] | 遍历数组元素 | jq '.items[]' |
| select(条件) | 只保留满足条件的元素 | select(.status=="active") |
| map(表达式) | 对每个元素做变换 | map(.name) |
| length | 数组或对象的长度 | jq '.items | length' |
| keys | 取对象的键列表 | jq 'keys' |
键名含连字符或特殊字符时要加引号写成 .data["build-id"];写成点号形式会被解析成减法表达式,得到报错或意外结果。
超过 2 的 53 次方的大整数会按浮点处理而丢精度。需要原样保留时把它按字符串取出来,不要让它参与数值运算。
输出与判断相关选项
| 选项 | 作用 | 场景 |
|---|---|---|
| -r | 字符串不加引号输出 | 拼进 shell 或写入配置 |
| -c | 每个结果压成一行 | 逐行处理与落盘 |
| -S | 对象键排序 | 两份 JSON 做 diff |
| -e | 按结果真假设置退出码 | 脚本里做条件判断 |
| --arg / --argjson | 注入外部变量 | 拼接查询条件 |
取深层字段直接用路径表达式 .a.b[0].c,要遍历数组用 map(),要挑字段组装新对象用 {名称: .字段}。把结果写回原文件时一定先输出到临时文件再替换,直接重定向会先清空源文件,jq 读到的是空输入。