使用 jq 在 Bash 中处理 JSON:从 API 调用到实战脚本
2026/9/17 19:29:04 网站建设 项目流程

使用 jq 在 Bash 中处理 JSON:从 API 调用到实战脚本

【免费下载链接】introduction-to-bash-scriptingFree Introduction to Bash Scripting eBook项目地址: https://gitcode.com/GitHub_Trending/in/introduction-to-bash-scripting

jq是一款轻量、灵活的命令行 JSON 处理器,用可移植 C 语言编写、零运行时依赖,是 Bash 脚本中解析 JSON 输出的利器。本文以"Introduction to Bash Scripting"开源电子书(ebook/en/content/018-working-with-json-in-bash-using-jq.md)为基础,围绕 QuizAPI 的真实 REST API 场景,完整讲解 jq 的安装、管道解析、数组索引与字段提取,并带你写出一个可复用的交互式 Bash JSON 脚本;读完即可在终端和脚本中自如处理任何 REST API 的 JSON 响应。

为什么用 jq 处理 Bash 中的 JSON

在现代 SysOps、DevOps 与日常开发工作中,REST API 返回的几乎都是 JSON 数据。Bash 本身并没有内置的 JSON 解析能力,而curl拉回来的原始 JSON 通常是一大串难以阅读的压缩文本。jq恰好解决了这个问题:

  • 它是命令行 JSON 处理器,天生适合与管道(pipe)配合,把curl的输出直接送入jq格式化或过滤;
  • 用可移植 C 编写,零运行时依赖,只需下载单个二进制或用系统包管理器一条命令即可安装;
  • 支持格式化、着色、索引访问、字段提取、过滤、变换等丰富操作,语法简洁,学习成本低。

在本书的章节体系中,本章建立在前面章节的变量(ebook/en/content/004-bash-variables.md)、函数(ebook/en/content/012-bash-functions.md)、重定向与管道(ebook/en/content/023-bash-redirection.md)知识之上,是"用 Bash 对接真实 REST API"的实用范例。

规划脚本:选择演示 API

为了让示例真实可运行,本书选用 QuizAPI 这个返回简单 JSON 输出的外部 REST API 作为演示对象:

  • API 地址:https://quizapi.io/
  • 免费 API Key 获取地址:https://quizapi.io/clientarea/settings/token
  • QuizAPI 对开发者免费,你只需注册并生成一个 Token 即可跟随本文操作

提示:后续示例中的API_KEY均需替换为你自己申请到的真实 Key。你也可以使用 QuizAPI URL Generator 生成更定制化的查询参数。

安装 jq

jq 的安装方式因操作系统而异,最直接的方式是使用各系统的包管理器:

  • Ubuntu/Debian
    sudo apt-get install jq
  • Fedora
    sudo dnf install jq
  • openSUSE
    sudo zypper install jq
  • Arch
    sudo pacman -S jq
  • macOS(Homebrew)
    brew install jq
  • macOS(MacPorts)
    port install jq

其他操作系统可参考 jq 官方下载页(jqlang.org/download)选择对应的预编译二进制或源码包。安装完成后,用以下命令验证安装并查看当前版本:

jq --version

用 jq 格式化解析 JSON 输出

安装好 jq 并拿到 QuizAPI 的 API Key 后,就可以直接在终端中解析 QuizAPI 的 JSON 输出了。

首先,把 API Key 存入一个变量:

API_KEY=YOUR_API_KEY_HERE

然后使用curl请求 QuizAPI 的一个端点:

curl "https://quizapi.io/api/v1/questions?apiKey=${API_KEY}&limit=10"

这里的${API_KEY}使用了变量插值。如 Bash Variables 章节所述,变量引用建议加上双引号并用花括号包裹,以避免分词(word splitting)和通配符展开带来的意外问题。

此时终端会打印一长串未经格式化的原始 JSON,可读性很差。借助管道,把curl的输出直接交给jq

curl "https://quizapi.io/api/v1/questions?apiKey=${API_KEY}&limit=10" | jq

注意命令结尾的| jqjq会自动对 JSON 进行缩进格式化并加上颜色高亮,输出立刻变得清晰易读。这正是管道(pipe)机制的经典应用:如 Redirection in Bash 章节所述,管道用|把前一个命令的 STDOUT 直接作为后一个命令的 STDIN 输入,从而把两个命令无缝串联起来。

用索引获取数组的第一个元素

QuizAPI 的/questions端点返回的是一个 JSON 数组。如果只想查看数组中的第一个元素,可以用.[0]指定索引:

jq '.[0]'

curl组合后的完整命令为:

curl "https://quizapi.io/api/v1/questions?apiKey=${API_KEY}&limit=10" | jq '.[0]'

执行后,终端只输出数组的第一个元素(即第一道题目及其全部字段)。.[0]中的方括号语法是 jq 访问数组元素的方式,0表示从 0 开始的第一个下标,与大多数编程语言的数组索引习惯一致。

只提取指定字段的值

很多时候你并不需要整个 JSON 对象,而只想取出某个 key 对应的值。以 QuizAPI 为例,它返回的每个元素包含题目(question)、答案(answers)、题目描述(description)等大量字段;如果只想拿到所有题目而不要其他信息,可以这样写:

jq '.[].question'

这里需要拆开理解:

  • .[]:遍历数组中的每一个元素。因为 QuizAPI 返回的是数组,用.[]告诉 jq "对数组中的每个元素分别处理";
  • .question:取出当前元素的question字段值。

两者连起来就是"取出数组中每个元素的 question 字段"。执行后,终端只打印出题目文本,其余字段全部被过滤掉,这正是 jq 在数据处理管道中的核心价值:解构嵌套结构、按需提取字段

jq 过滤表达式速查

表达式作用
jq格式化并着色整个 JSON
jq '.[0]'取出数组第一个元素
jq '.[]'遍历数组所有元素
jq '.field'取出对象的某个字段
jq '.[].field'取出数组中每个元素的某个字段
jq '.[0].field'取出数组第一个元素的某个字段
jq '.answers.answer_a'访问嵌套对象(多级字段)

在 Bash 脚本中综合运用 jq

掌握了 jq 的基本操作后,把它们组合进一个完整的 Bash 脚本。下面的脚本完成以下任务:

  • 只取返回结果中的第一道题目;
  • 取出该题的所有答案选项;
  • 将各答案分别赋给独立变量;
  • 在终端打印题目和答案。

提示:运行前请务必将API_KEY替换为你真实的 QuizAPI Key。

#!/bin/bash ## # 调用 QuizAPI 并把输出存入变量 ## output=$(curl 'https://quizapi.io/api/v1/questions?apiKey=API_KEY&limit=10' 2>/dev/null) ## # 只保留第一道题目 ## output=$(echo "$output" | jq '.[0]') ## # 取出题目文本 ## question=$(echo "$output" | jq '.question') ## # 取出四个答案选项 ## answer_a=$(echo "$output" | jq '.answers.answer_a') answer_b=$(echo "$output" | jq '.answers.answer_b') answer_c=$(echo "$output" | jq '.answers.answer_c') answer_d=$(echo "$output" | jq '.answers.answer_d') ## # 打印题目与答案 ## echo " Question: ${question} A) ${answer_a} B) ${answer_b} C) ${answer_c} D) ${answer_d} "

脚本要点逐段解析

1. 命令替换(Command Substitution)获取 API 响应

output=$(curl 'https://quizapi.io/api/v1/questions?apiKey=API_KEY&limit=10' 2>/dev/null)

$(...)是 Bash 的命令替换语法:先执行括号内的命令,再把命令的 STDOUT 作为字符串赋给output变量。2>/dev/null把 STDERR 重定向到/dev/null丢弃——如 Redirection in Bash 章节所述,2>重定向错误流,而/dev/null是"只进不出"的伪设备,适合在脚本中静默忽略不必要的错误提示(例如 curl 的进度信息或告警)。

2. 多次管道过滤,逐层缩小数据

output=$(echo "$output" | jq '.[0]') question=$(echo "$output" | jq '.question')

第一次过滤用jq '.[0]'把整个数组缩减为第一道题目;之后的每次提取都用echo "$output" | jq '...'从该题目对象中取出所需字段。这种"每次提取、重新赋值"的写法直白易懂,方便调试每一步的中间结果;在生产脚本中也可以一次性用jq -r '.[0] | .question'之类更紧凑的写法,但分步方式更利于学习与排错。

3. 嵌套字段访问

answer_a=$(echo "$output" | jq '.answers.answer_a')

answers本身是一个嵌套对象,jq '.answers.answer_a'用点号链式访问多级字段:先取answers对象,再取其中的answer_a字段。四个答案选项分别赋给answer_a~answer_d四个变量。

4. 输出变量引用

echo " Question: ${question} A) ${answer_a} ... "

双引号包裹的echo中,${question}${answer_a}等会被展开为前面 jq 提取的字段值。按照 Bash Variables 的最佳实践,变量引用一律使用双引号与花括号,避免值中的空格被分词破坏。

运行脚本即可在终端看到类似如下的输出:

Question: 以下哪个命令用于查看当前目录内容? A) ls B) cd C) pwd D) cat

更进一步:把脚本变成交互式测验

基础脚本已经能自动获取题目和答案,还可以继续增强,让它变成真正"可选答案"的交互式工具:读取用户输入、判断对错、循环出题。本书 Creating an interactive menu in Bash 章节已经演示了如何用read读取用户输入,并用case语句根据输入分支执行不同函数——同样的模式完全可以叠加在本章的 jq 脚本之上:

#!/bin/bash output=$(curl 'https://quizapi.io/api/v1/questions?apiKey=API_KEY&limit=1' 2>/dev/null) question=$(echo "$output" | jq '.[0].question') answer_a=$(echo "$output" | jq -r '.[0].answers.answer_a') answer_b=$(echo "$output" | jq -r '.[0].answers.answer_b') answer_c=$(echo "$output" | jq -r '.[0].answers.answer_c') answer_d=$(echo "$output" | jq -r '.[0].answers.answer_d') echo -e "\n$question\n" echo "1) $answer_a" echo "2) $answer_b" echo "3) $answer_c" echo "4) $answer_d" echo "" read -p "你的选择 (1-4): " choice case $choice in 1) echo "你选择了 A" ;; 2) echo "你选择了 B" ;; 3) echo "你选择了 C" ;; 4) echo "你选择了 D" ;; *) echo "无效选项" ;; esac

这里的jq -r选项表示输出原始字符串(raw string),去掉 JSON 字符串自带的双引号,更适合直接展示给用户;read -p提示输入并把结果存入变量,case则根据选择执行对应分支。

结合本书其他章节的进阶用法

jq 在本电子书的后续实战章节中还会反复出现,例如:

  • Working with Cloudflare API with Bash:调用 Cloudflare API 时同样用 curl + jq 提取 DNS 记录、缓存状态等 JSON 字段;
  • BASH 日志解析脚本:配合 awk、sort、uniq 等文本工具处理日志,与 jq 的"提取-聚合"思路一脉相承。

这些章节的共同模式是:curl 获取数据 → jq 提取字段 → Bash 变量承载结果 → 循环/函数组织逻辑,掌握 jq 就等于打通了 Bash 与任意 JSON API 之间的最后一公里。

结论

jq是一个功能强大的命令行工具,它让你可以直接在 Bash 终端中处理和解析 JSON,无需引入 Python、Node.js 等额外运行时。配合 curl 与管道,你可以轻松地在 Bash 中对接各类 REST API:格式化响应、按索引取值、按字段过滤、嵌套访问,再结合命令替换、变量、函数与 case 语句,就能快速构建出真实的自动化脚本。

更多细节可查阅 jq 官方手册(jqlang.github.io/jq/manual),了解mapselectlength-c--arg等进阶特性;QuizAPI 的完整接口文档则可在其官网 docs 中查看。完整的 Bash 基础知识体系,可继续阅读本书的其他章节,例如 Writing your first Bash script 与 Creating custom bash commands,将本节学到的 jq 能力应用到更复杂的自动化场景中。

【免费下载链接】introduction-to-bash-scriptingFree Introduction to Bash Scripting eBook项目地址: https://gitcode.com/GitHub_Trending/in/introduction-to-bash-scripting

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询