Linux 下载、安装 jq 1.8.2,轻量灵活的 JSON 命令行处理器,切片、过滤、映射一条命令搞定(附安装包jq-linux-amd64)
文章目录

1. jq 简介
jq 是一款轻量而灵活的命令行 JSON 处理器,官方 README 用一句话概括它的定位:面向 JSON 数据的 sed、awk、grep。它由 Stephen Dolan 于 2012 年创建,最初用 Haskell 写成,随后移植为可移植的 C 语言实现。代码零运行时依赖,发布形态就是一个单文件可执行程序。
jq 的发展轨迹在开源项目里颇为特别。它在 2015 年的 1.5 版本中加入正则表达式支持与大量语言特性,随后经历了近五年的沉寂,直到 2023 年 9 月社区把治理权迁入 jqlang 组织、Stephen Dolan 将仓库转交,才以 1.7 版本重启发布节奏。此后 1.7.1、1.8.0、1.8.1、1.8.2 依次落地,CI、跨平台构建、Docker 镜像与 OSS-Fuzz 集成也一并补齐。截至 2026 年 9 月,项目在 GitHub 上拥有约 35,600 颗星标、1,800 余个 Fork。
如今 jq 几乎是命令行环境里的默认配件:Shell 脚本解析 API 返回值、Kubernetes 与 Docker 的 JSON 输出提取、CI 流水线里改写配置文件,到处都能见到它的身影。它还催生了一批再实现与周边工具,如 Go 写的 gojq、Rust 写的 jaq,以及 fq、jq-lsp 等。
jq 的核心特点:
- 一条命令完成结构化数据处理:切片、过滤、映射、排序、分组、递归下降,通过管道把多个过滤器串起来,表达能力接近一门小型查询语言
- 零运行时依赖:用可移植 C 编写,官方发布的 Linux 二进制为完全静态链接,不依赖 glibc 或其他系统库,拷贝到任意发行版即可运行
- JSON 原生语义:输入输出都是 JSON,配合
-r输出原始字符串、-c输出紧凑格式、-s把整个输入读成数组,可无缝嵌入 Shell 管道 - 完整的过滤语言:内置
map、select、reduce、foreach、group_by、sort_by、路径操作paths/getpath/setpath等函数,支持自定义函数与模块导入 - 正则与字符串处理:支持
test、match、capture、sub、gsub(基于内置 oniguruma),以及ltrimstr、rtrimstr、splits、ascii_downcase等字符串函数 - 格式化与编码:
@base64、@base64d、@csv、@tsv、@html、@uri、@sh、@json等格式化器,可在 Shell 与 JSON 之间安全往返 - 日期时间处理:
fromdateiso8601、todateiso8601、strptime、mktime、gmtime等,可完成时间戳转换与时区计算 - 可编程的日志与调试:
debug、stderr、input/inputs、--arg/--argjson传参,方便写成可复用的脚本 - MIT 许可证:可自由用于商业项目,文档部分采用 CC BY 3.0
2. jq-1.8.2 版本亮点
该版本汇集了 21 位贡献者 的 63 条 贡献。
jq 1.8.2 于 2026 年 6 月 20 日发布,是自 1.8.1 以来的一个补丁版本,主体是安全修复与缺陷修复,同时扩展了平台构建。它的安全修复数量之多,使它成为一次建议尽快升级的版本。
安全修复:
该版本集中修复了 16 个 CVE 与 2 个 GHSA 安全公告,其中多数为栈溢出、越界读写一类的内存安全问题,且大多可以通过构造恶意的 JSON 输入或 jq 程序触发:
- 堆缓冲区溢出:修复
jvp_string_append与jvp_string_copy_replace_bad中的堆溢出(CVE-2026-32316) - 栈溢出防护:为路径操作(
jv_setpath、jv_getpath、jv_delpaths,CVE-2026-33947)、contains包含检查(CVE-2026-40612)、对象递归合并(CVE-2026-43896)、深层结构相等性与比较(CVE-2026-47770)以及深层嵌套值的释放分别加上深度限制 - 解析器与程序加载:修复 JSON 解析器中的 NUL 截断(CVE-2026-33948)、
jv_parse_sized()的越界读取(CVE-2026-39979)、-f加载程序文件时的 NUL 截断(CVE-2026-41256),并拒绝模块导入路径中内嵌的 NUL 字节(CVE-2026-43895) - 拒绝服务防护:随机化哈希种子,缓解哈希碰撞攻击(CVE-2026-40164);拒绝长度超过
DEC_MAX_DIGITS(999999999)的数字字面量(CVE-2026-43894);检测循环模块导入(CVE-2026-44777) - 整数溢出与内存管理:修复
stack_reallocate(CVE-2026-41257)、tokenadd(GHSA-hj52-j2c9-r8r4)中的有符号整数溢出,修复args2obj()数组参数路径的释放后使用(GHSA-gf4g-95wj-4q4r),以及若干内存泄漏与重复释放 - 此外还限制函数参数与定义的个数、为字符串解析器预分配
tokenbuf,修复implode的字符串长度边界(CVE-2026-54679)等问题
平台支持扩展:
- 新增 Windows arm64 构建
- Docker 镜像支持 arm/v7 架构
- 更新 GPG 签名密钥,并将证明(attestation)打包文件作为发布产物上传,可通过
gh attestation verify --bundle jq-attestation.json做免认证校验
命令行改进:
- 最大打印深度从 256 提升到 10000,深层嵌套结构不再被过早截断
- 错误信息截断时会补全闭合定界符,输出更好读
- 修复原始输入(
--raw-input)参数破坏多字节字符的问题 - 修复带错误的模块被导入两次时崩溃的问题
- 去掉
die函数输出中多余的空格
函数行为修复:
rtrimstr("")不再总是输出""- 修复
del(.[nan])的死循环与未定义行为 - 重构
@uri与@urid,修复多字节 UTF-8 被破坏的问题 tonumber与toboolean现在会拒绝内嵌空字节的字符串- 修复取模运算的未定义行为、
f_env边界检查中指针相减顺序颠倒、f_strflocaltime缺少有效性检查等 - 修复 32 位平台上的 2038 年问题
from_entries的定义中改用//取代//=
构建与测试:
- 新增 Solaris 平台支持
- 支持
--disable-maintainer-mode,以及源码目录与构建目录不同的构建方式 - 生成 man 手册页时遵循
SOURCE_DATE_EPOCH,便于可复现构建 - 修复
jq_testsuite的崩溃与资源泄漏,修复 UTF-8 辅助函数中的未定义指针运算
3. 获取安装包
如果访问 GitHub 不便,安装包及中文文档:https://hanshuixin.org/go/226D(内含 jq-linux-amd64、README 中英对照、发布说明中英对照、LICENSE 和源码)。
适用于 Linux x86_64(amd64)。
jq 其他版本:https://hanshuixin.org/resource/software_integrated_package/Linux/jq
Linux安装jq-1.8.2(jq-linux-amd64).zip
├── jq-linux-amd64
├── Linux安装jq-1.8.2(jq-linux-amd64).pdf
├── README/
│ ├── README.md
│ └── README-中文版.md
├── 发布说明/
│ ├── RELEASE-NOTES.md
│ └── RELEASE-NOTES-中文版.md
├── 源码/
│ └── jq-1.8.2.zip
└── LICENSE4. 安装
jq 无需安装。把整合包根目录中的 jq-linux-amd64 拷到 PATH 中的任意目录,赋予执行权限即可使用:
chmod +x jq-linux-amd64
sudo mv jq-linux-amd64 /usr/local/bin/jq
jq --version也可以用改名方式保留多版本共存,例如放到 /usr/local/bin/jq-1.8.2 再建软链接。
该二进制为完全静态链接,不依赖 glibc 或任何运行时库,glibc 与 musl 发行版都能直接运行。若需要放到容器镜像中使用,直接把该文件 COPY 进去即可,无需再安装任何包。
整合包内的 jq-linux-amd64 与官方发布的同名文件逐字节一致,其 SHA-256 为 b1c22172dd303f3be49e935aa56aa48a8b7a46e0bc838b4997d3bb451495870f,可与官方 sha256sum.txt 核对。
若发行版的包管理器已提供 jq,也可以用
apt install jq、dnf install jq、apk add jq等方式安装,但发行版仓库中的版本通常滞后于上游,且未必包含 1.8.2 的安全修复。
5. 使用
5.1 基本过滤
jq 的用法是把一个过滤器程序作用在 JSON 输入上,结果输出到标准输出。
# 格式化输出(美化缩进)
jq . package.json
# 取字段
jq '.name' package.json
# 取嵌套字段
jq '.dependencies.react' package.json
# 取数组元素
jq '.[0]' data.json
jq '.[-1]' data.json # 最后一个元素
jq '.[2:5]' data.json # 切片
# 遍历数组
jq '.[]' data.json过滤器用 | 串联,. 表示当前值:
# 取出所有依赖名
jq '.dependencies | keys[]' package.json
# 把嵌套结构压平
jq '.users[] | .name' data.json5.2 从管道与 API 读取
jq 最常见的用法是接在 curl、docker、kubectl 之后处理 JSON 输出:
# 处理 HTTP API 返回值
curl -s https://api.github.com/repos/jqlang/jq | jq '.stargazers_count'
# 从 kubectl 输出中提取镜像名
kubectl get pods -o json | jq -r '.items[].spec.containers[].image'
# 处理 docker inspect 的输出
docker inspect nginx | jq '.[0].NetworkSettings.IPAddress'常用输出控制选项:
| 选项 | 说明 |
|---|---|
-r / --raw-output |
字符串结果不带引号输出,便于赋值给 Shell 变量 |
-c / --compact-output |
紧凑输出,每行一个 JSON 对象,适合喂给 while read |
-s / --slurp |
把整个输入流读成一个数组再处理 |
-n / --null-input |
不使用输入,通常配合 --arg 构造 JSON |
-e / --exit-status |
依据最后一个输出决定退出码,便于在脚本中做判断 |
--tab、--indent n |
指定缩进方式 |
# 逐行处理 JSON Lines
cat events.jsonl | jq -c 'select(.level == "error") | .msg'
# 直接构造 JSON
jq -n --arg name jq --arg ver 1.8.2 '{name: $name, version: $ver}'5.3 条件筛选与变换
# 按条件筛选
jq '.[] | select(.age > 30)' users.json
# 映射
jq 'map(.name)' users.json
jq '[.[] | .name]' users.json
# 排序与分组
jq 'sort_by(.age)' users.json
jq 'group_by(.dept)' users.json
jq 'unique_by(.dept)' users.json
# 聚合
jq '[.[] | .price] | add' orders.json
jq 'length' data.json
jq '.[] | .price' orders.json | jq -s 'min, max, add/length'
# 构造新对象
jq '.[] | {n: .name, a: .age}' users.json
jq '{total: length, names: map(.name)}' users.jsonreduce 与 foreach 用于需要累积状态的场景:
# 求和
jq 'reduce .[] as $x (0; . + $x)' nums.json
# 带中间输出
jq 'foreach .[] as $x (0; . + $x)' nums.json5.4 字符串、正则与格式化
# 字符串函数
jq 'ltrimstr("v")' <<< '"v1.8.2"'
jq 'ascii_downcase' <<< '"HELLO"'
jq 'split(",")' <<< '"a,b,c"'
jq 'test("^jq")' <<< '"jqlang"'
jq 'capture("(?<maj>[0-9]+)\\.(?<min>[0-9]+)")' <<< '"1.8"'
# 替换
jq 'sub("a"; "A")' <<< '"abc"'
jq 'gsub("a"; "A")' <<< '"banana"'
# 格式化器
jq '@base64' <<< '"hello"'
jq -r '@csv' <<< '[["a","b"],["1","2"]]'
jq -r '@tsv' <<< '["a","b"]'
jq -r '@uri' <<< '"a b/c"'
jq -r '@sh' <<< '"it'"'"'s"'5.5 日期时间
# Unix 时间戳 -> ISO 8601
jq 'todateiso8601' <<< '1750000000'
# ISO 8601 -> Unix 时间戳
jq 'fromdateiso8601' <<< '"2026-06-20T14:11:27Z"'
# 自定义格式解析
jq 'strptime("%Y-%m-%d") | mktime' <<< '"2026-06-20"'
# 当前时间
jq -n 'now | todateiso8601'5.6 路径操作与递归
# 列出所有叶子路径
jq 'paths(scalars)' data.json
# 按路径取值 / 设值 / 删除
jq 'getpath(["a","b"])' data.json
jq 'setpath(["a","b"]; 1)' data.json
jq 'delpaths([["a","b"]])' data.json
# 递归下降,找出所有同名键
jq '.. | .name? // empty' data.json
# 递归改写键名
jq 'walk(if type == "object" then with_entries(.key |= ascii_upcase) else . end)' data.json5.7 传入参数与编写脚本
--arg 传入字符串,--argjson 传入 JSON 片段,$ARGS 可读取全部位置参数与命名参数:
jq -n --arg env prod --argjson port 8080 '{env: $env, port: $port}'
# 使用环境变量
jq -n --arg home "$HOME" '{home: $home}'
# 读取外部文件内容作为变量
jq --rawfile content notes.md -n '{body: $content}'
# jq 内置访问环境变量
jq -n '$ENV.HOME'较长的过滤器可写成脚本文件,通过 -f 加载,并可用 import/include 组织模块:
jq -f transform.jq data.json
# 从指定目录查找模块
jq -L ./lib -f transform.jq data.json5.8 调试与错误处理
# 打印中间值到 stderr,不影响标准输出
jq '.a | debug | .b' data.json
# 输出到 stderr
jq '.msg | stderr' data.json
# 捕获错误
jq 'try (.a.b.c) catch "not found"' data.json
# 提供默认值(// 运算符)
jq '.items // []' data.json
jq '.user.name? // "anonymous"' data.json-e 选项会依据结果决定退出码,false 与 null 返回 1,其余返回 0,适合在 Shell 脚本中直接做条件判断。