使用 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注意命令结尾的| jq。jq会自动对 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),了解map、select、length、-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),仅供参考