jq是Linux处理JSON的事实标准工具,安装需按发行版选择对应包管理命令,使用时必须加-r获取原始字符串,修改文件应避免重定向覆盖,数组操作须区分.[]与|=语义。

jq 是 Linux 命令行处理 JSON 的事实标准工具,不是“可选方案”,而是目前最可靠、最轻量、最广泛支持的方案。没有它,你得写脚本或临时转成 Python —— 不值得。
怎么装 jq?看发行版,别硬套命令
不同系统包管理器名字和源策略不同,硬记 apt install jq 或 yum install jq 容易翻车:
- Ubuntu/Debian:先
sudo apt update,再sudo apt install jq(旧镜像可能需加-y) - CentOS 7 / RHEL 7:必须先启用 EPEL:
sudo yum install epel-release,再sudo yum install jq - CentOS 8+ / RHEL 8+ / Fedora:直接
sudo dnf install jq - Alpine(Docker 场景常见):
apk add jq
装完立刻验证:jq --version。如果报 command not found,说明没装上或 PATH 没刷新 —— 别跳过这步。
解析字段时为什么输出带引号?-r 参数不是可选项
默认输出是合法 JSON 字符串,所以 jq '.name' 返回 "alice",不是 alice。很多后续命令(比如 grep、if [ ] 判断)会因此失败。
- 要原始字符串(raw output),必须加
-r:jq -r '.name' user.json - 嵌套字段也一样:
jq -r '.profile.city' user.json - 数组展开时加
-r才能逐行输出纯文本:jq -r '.hobbies[]' data.json
漏掉 -r 是新手最常踩的坑 —— 看起来“取到了”,但后续脚本里一比较就 false。
修改 JSON 文件时,重定向 > 会清空原文件?小心原子性
jq '.age = 25' data.json > data.json 这种写法在绝大多数 shell 下是**未定义行为**:shell 会先截断 data.json,再执行 jq,结果是空文件。
- 安全做法:用临时文件 +
mv:jq '.age = 25' data.json > tmp.json && mv tmp.json data.json - 更优解:装
moreutils后用sponge(它缓存全部输入再写入):jq '.age = 25' data.json | sponge data.json - 别依赖
sed -i或正则改 JSON —— JSON 格式敏感,缩进、逗号、引号稍错就整个失效
真正线上脚本里,宁可多一步 mv,也不要赌 shell 的重定向顺序。
数组操作最容易出错:.[] 和 |= 的区别必须分清
想给每个用户加一个 status 字段,下面两种写法效果完全不同:
-
jq '.users[] += {"status": "active"}'→ 错。这是对每个元素做+=,但+=期望右边是同类型值(如数组拼接),对象不能直接+= -
jq '.users[] |= . + {"status": "active"}'→ 对。用|=把每个元素传给右侧表达式,. + {...}才是合法的对象合并 - 删数组中某个元素要用
del(.list[] | select(.id == 2)),不是del(.list[].id == 2)—— 后者语法错误
数组遍历的语法糖(如 .items[].name)只适合读取;一旦要修改,就得用 |= 或 | 显式传递上下文 —— 这点文档里不强调,但实际踩坑率极高。


















