macOS 下载、安装 jq 1.8.2,轻量灵活的命令行 JSON 处理器,切片、过滤、映射一条管道搞定(附安装包jq-macos-arm64)

发布于 2026/9/16 · 1 阅读
jqJSON命令行工具JSON 处理器jq 教程macOS开源软件数据处理Shell 脚本JSON 解析
jq 是轻量灵活的命令行 JSON 处理器,用可移植的 C 语言写成、零运行时依赖,以过滤器与管道完成 JSON 的切片、过滤、映射和转换。本文介绍 jq 1.8.2 的安全修复与版本亮点、macOS 安装方式与常用用法。

封面.png

1. jq 简介

jq 是一款命令行 JSON 处理器(command-line JSON processor),由 Stephen Dolan 于 2012 年创建。它常被描述为「JSON 世界里的 sed」——sed 以行为单位处理文本,而 jq 以 JSON 值为单位工作,把 JSON 当作原生数据类型,而不是一串需要正则去啃的字符。早期实现使用 Haskell 编写,随后移植到 C 语言。2013 年的 1.3、2014 年的 1.4、2015 年的 1.5(引入正则、时间日期与数学函数、try/catch、解构、流式解析器与模块系统)与 2018 年的 1.6,构成了它早期的发布脉络。在 1.6 之后项目沉寂了约五年,随后治理迁移到 jqlang 组织,由新的维护者接手重启:重建 CI 与发布流程、补齐多平台二进制与 Docker 镜像、接入 OSS-Fuzz,并在 2023 年 9 月发布 1.7,2025 年 6 月发布 1.8.0。如今 jq 在 GitHub 上已收获约 3.5 万颗星,官网为 jqlang.org。

用 jq 处理 JSON,只需要把一段过滤表达式(filter)写在命令行上,数据从标准输入流进来、结果流出去。它把 JSON 的切片、过滤、映射和转换抽象成了一套小巧的函数式语言:.foo 取名,.[] 展开数组,select 挑元素,map 批量变换,多个处理环节用 | 串成管道。JSON 如今是 Web API、云 CLI、Kubernetes 和各类配置文件的通用语,jq 也因此成为了 API 使用者、Shell 脚本作者、SRE 与 CI 维护者人手一个的基础工具。

jq 的核心特点:

  • 零依赖单文件:用可移植的 C 语言编写,没有任何运行时依赖,一个二进制文件复制到任何机器上就能跑
  • 小巧但完整:切片、过滤、映射、转换之外,还原生支持正则、日期时间、数学函数、模块与流式解析
  • 函数式管道风格:| 连接多个处理环节,每一步的输入输出都是 JSON,组合能力强
  • 纯命令行交互:配合 Shell 的双引号与单引号即可完成绝大多数日常数据处理,也适合写进脚本与 CI
  • 生态广泛:衍生出 gojq(Go)、jaq(Rust)、jqjq、jq-web 等多个重新实现,理念还被 yq 等工具带到了 YAML、XML、TOML
  • 开源免费:依据 MIT 许可证发布

2. 1.8.2 版本亮点

该版本汇集了 22 位贡献者59 条 贡献。

这是一个补丁版本,主题是修复 1.8.1 以来的安全问题与缺陷,同时新增了 Windows arm64 与 Docker arm/v7 的构建产物。

安全修复(本版重点,共修复 18 个 CVE 与 2 个 GHSA 安全公告):

编号 修复内容
CVE-2026-32316 修复字符串拼接 jvp_string_appendjvp_string_copy_replace_bad 中的堆缓冲区溢出
CVE-2026-33947 限制路径深度,防止 jv_setpathjv_getpathjv_delpaths 中的栈溢出
CVE-2026-33948 修复 JSON 解析器中的 NUL 截断
CVE-2026-39956 _strindices 补齐运行时类型检查
CVE-2026-39979 修复 jv_parse_sized() 中的越界读取
CVE-2026-40164 随机化哈希种子,缓解哈希碰撞型拒绝服务(DoS)攻击
CVE-2026-40612 限制包含判断的递归深度,防止 contains 中的栈溢出
CVE-2026-41256 修复通过 -f 加载的程序文件中的 NUL 截断
CVE-2026-41257 修复 stack_reallocate 中的有符号整型溢出
CVE-2026-43894 拒绝长度超过 DEC_MAX_DIGITS(999999999)的数字字面量
CVE-2026-43895 拒绝模块导入路径中内嵌的 NUL 字节
CVE-2026-43896 限制对象递归合并的深度,防止栈溢出
CVE-2026-44777 检测循环模块导入,防止栈溢出
CVE-2026-47770 为深层结构的相等性与比较递归加上保护
CVE-2026-49839 修复原始文件(raw file)加载中的堆缓冲区溢出
CVE-2026-54679 收紧字符串长度边界,并在 implode 中正确传递无效的 jv 值
GHSA-gf4g-95wj-4q4r 修复 args2obj() 数组参数路径中的释放后使用(use-after-free)
GHSA-hj52-j2c9-r8r4 修复 tokenadd 中的有符号整型溢出,防止缓冲区溢出

此外还限制了函数参数与函数定义的数量以预防段错误,为字符串解析器预分配 tokenbuf 以避免未定义行为,并修复了若干内存泄漏与重复释放问题。

发布工程:新增 Windows arm64 构建,Docker 镜像支持 arm/v7 架构,更新了 GPG 签名密钥,并把证明包(attestation bundle)作为发布产物上传——现在可以通过 gh attestation verify --bundle jq-attestation.json 免登录校验下载到的二进制文件。

命令行变更:改进错误信息截断处理,补全收尾的定界符;移除 die 函数输出中多余的空格;修复原始输入(raw input)参数会破坏多字节字符的问题;修复带错误的模块被导入两次时导致的崩溃;将最大打印深度从 256 提高到 10000。

函数行为修复:修复 rtrimstr("") 始终输出 ""del(.[nan]) 中的死循环与未定义行为、@uri@urid 破坏多字节 UTF-8、取模运算符中的未定义行为,以及 32 位平台上的 2038 年问题;tonumbertoboolean 现在会拒绝内嵌空字节的字符串;from_entries 的定义改用 // 替代 //=

构建与文档:新增 Solaris 平台支持,支持 --disable-maintainer-mode 与「源码目录 != 构建目录」的构建方式,生成 man 手册页时遵循 SOURCE_DATE_EPOCH,并修复了测试套件中的多处崩溃、资源泄漏与断言问题。

3. 获取安装包

如果访问 GitHub 不便,安装包及中文文档:https://hanshuixin.org/go/226C(内含 jq-macos-arm64、README 中英对照、发布说明中英对照、LICENSE 和源码)。

适用于 Apple Silicon(ARM64,M 系列芯片)的 Mac。若你的 Mac 是 Intel 芯片,请选择 x86_64 版本的整合包。

jq 其他版本https://hanshuixin.org/resource/software_integrated_package/macOS/jq

macOS安装jq-1.8.2(jq-macos-arm64).zip
├── jq-macos-arm64
├── macOS安装jq-1.8.2(jq-macos-arm64).pdf
├── README/
│   ├── README.md
│   └── README-中文版.md
├── 发布说明/
│   ├── RELEASE-NOTES.md
│   └── RELEASE-NOTES-中文版.md
├── 源码/
│   └── jq-1.8.2.zip
└── LICENSE

4. 安装

jq 官方在 macOS 上只提供独立二进制文件,没有安装器。把整合包根目录中的 jq-macos-arm64 复制到 PATH 中的某个目录,并赋予可执行权限,即可在终端里直接使用 jq 命令:

chmod +x jq-macos-arm64
sudo mv jq-macos-arm64 /usr/local/bin/jq

验证安装:

jq --version

如果系统提示该文件已被隔离(quarantine),可以手动解除:

sudo xattr -d com.apple.quarantine /usr/local/bin/jq

jq 没有任何运行时依赖,也不需要配置环境变量即可使用。如果你已经用 Homebrew 或其他包管理器装过 jq,建议先卸载旧版本,避免 PATH 中出现两个 jq。

5. 使用

5.1 基础用法

jq 的用法是 jq '<过滤器>' [文件...],不指定文件时从标准输入读取。最常用的几个过滤器:

# 格式化输出(美化打印),'.' 是恒等过滤器
echo '{"name":"jq","version":"1.8.2"}' | jq '.'

# 取字段,`.` 表示当前值,链式取出嵌套字段
echo '{"a":{"b":42}}' | jq '.a.b'

# `.[]` 展开数组或对象的全部元素
echo '[1,2,3]' | jq '.[]'

# 取数组中满足条件的元素
echo '[{"n":"a","p":5},{"n":"b","p":20}]' | jq '.[] | select(.p > 10) | .n'

# `|` 把上一步的输出接到下一步的输入
cat package.json | jq '.dependencies | keys'

jq 也支持从命令行直接构造数据,-n 表示不读取输入、以 null 作为起点:

jq -n '{name:"jq", tags:["json","cli"]}'

5.2 常用命令行选项

选项 作用
-r / --raw-output 字符串结果不加引号直接输出,适合接进 Shell 变量与管道
-c / --compact-output 紧凑输出,每个 JSON 值占一行,便于逐行处理与日志
-s / --slurp 把全部输入读成一个数组再处理
-n / --null-input 不读输入,以 null 为起点运行过滤器
-e / --exit-status 用输出结果决定退出码,便于在脚本中做条件判断
-S / --sort-keys 输出时按键名排序
-j / --join-output 类似 -r,但不在输出末尾追加换行
-R / --raw-input 把输入当作纯文本而非 JSON,逐行读入
--arg name value 从命令行传入字符串变量,在过滤器里用 $name 引用
--argjson name value 同上,但传入的是 JSON 值
--slurpfile / --rawfile 把文件内容读成变量,前者按 JSON 解析,后者保持原文
-f file 从文件读取过滤器,把较长的程序写进 .jq 文件
--indent n / --tab 指定缩进宽度或使用制表符
--stream 以流式方式解析输入,处理超出内存的大文件

5.3 常用内置函数

函数 作用
map(f) 对数组每个元素应用 f,返回新数组
select(f) 保留满足条件 f 的元素,其余丢弃
sort_by(f) / group_by(f) f 的结果排序、分组
unique / unique_by(f) 去重
add 把数组元素求和(数字相加、字符串拼接、数组拼接)
length / keys / has(k) 取长度、取键名、判断键是否存在
to_entries / from_entries 对象与 [{key,value}] 数组之间的互转
paths / getpath / setpath / delpaths 按路径数组读取、修改、删除深层字段
.. 递归下降,遍历全部层级的值
walk(f) 自底向上递归地把 f 应用到每个值上
// 备选运算符,左侧为 nullfalse 时取右侧
try f catch g 捕获错误并处理
reduce / foreach 归约与迭代,用于累加、构造新结构
tostring / tonumber 类型转换
@csv / @tsv / @base64 / @uri 格式化为 CSV、TSV、Base64、URL 编码

5.4 一个完整例子

把一份 JSON 日志里状态码非 200 的请求筛出来,按耗时倒序排,输出成 CSV:

jq -r '
  [.[] | select(.status != 200)]
  | sort_by(.duration) | reverse
  | .[] | [.time, .method, .path, .status, .duration]
  | @csv
' access.json

把长过滤器写进文件、交给 -f 执行,再配合 --arg 从 Shell 传参,是脚本里更常见的写法:

cat > errors.jq <<'EOF'
.[] | select(.status >= 400) | {env: $env, time, path, status}
EOF

jq -c -f errors.jq --arg env "$ENV_NAME" access.json