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

发布于 2026/9/16 · 1 阅读
jqJSON命令行工具JSON解析LinuxShell数据处理文本处理开源软件C语言
jq 是轻量灵活的命令行 JSON 处理器,被称作 JSON 界的 sed 与 awk。本文提供 jq 1.8.2 中文文档、发布说明中英对照,以及 Linux x86_64 静态编译安装包。

封面.png

1. jq 简介

jq 是一款轻量而灵活的命令行 JSON 处理器,官方 README 用一句话概括它的定位:面向 JSON 数据的 sedawkgrep。它由 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,以及 fqjq-lsp 等。

jq 的核心特点:

  • 一条命令完成结构化数据处理:切片、过滤、映射、排序、分组、递归下降,通过管道把多个过滤器串起来,表达能力接近一门小型查询语言
  • 零运行时依赖:用可移植 C 编写,官方发布的 Linux 二进制为完全静态链接,不依赖 glibc 或其他系统库,拷贝到任意发行版即可运行
  • JSON 原生语义:输入输出都是 JSON,配合 -r 输出原始字符串、-c 输出紧凑格式、-s 把整个输入读成数组,可无缝嵌入 Shell 管道
  • 完整的过滤语言:内置 mapselectreduceforeachgroup_bysort_by、路径操作 paths/getpath/setpath 等函数,支持自定义函数与模块导入
  • 正则与字符串处理:支持 testmatchcapturesubgsub(基于内置 oniguruma),以及 ltrimstrrtrimstrsplitsascii_downcase 等字符串函数
  • 格式化与编码@base64@base64d@csv@tsv@html@uri@sh@json 等格式化器,可在 Shell 与 JSON 之间安全往返
  • 日期时间处理fromdateiso8601todateiso8601strptimemktimegmtime 等,可完成时间戳转换与时区计算
  • 可编程的日志与调试debugstderrinput/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_appendjvp_string_copy_replace_bad 中的堆溢出(CVE-2026-32316)
  • 栈溢出防护:为路径操作(jv_setpathjv_getpathjv_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 被破坏的问题
  • tonumbertoboolean 现在会拒绝内嵌空字节的字符串
  • 修复取模运算的未定义行为、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
└── LICENSE

4. 安装

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 jqdnf install jqapk 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.json

5.2 从管道与 API 读取

jq 最常见的用法是接在 curldockerkubectl 之后处理 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.json

reduceforeach 用于需要累积状态的场景:

# 求和
jq 'reduce .[] as $x (0; . + $x)' nums.json

# 带中间输出
jq 'foreach .[] as $x (0; . + $x)' nums.json

5.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.json

5.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.json

5.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 选项会依据结果决定退出码,falsenull 返回 1,其余返回 0,适合在 Shell 脚本中直接做条件判断。