jq 命令行 JSON 处理实战——调试 API 与处理日志的瑞士军刀
为什么要学 jq? 如果你经常跟 API 打…
为什么要学 jq?
如果你经常跟 API 打交道、在终端里处理日志、或者调试 Docker 返回的 JSON 数据,那你一定经历过这种场景:curl 一个接口回来一大坨 JSON,密密麻麻挤在一起,肉眼根本没法看。要么复制出来贴到在线格式化工具里,要么写个 Python 脚本慢慢解析。
jq 就是专门解决这个痛点的——一个命令行下的 JSON 处理利器,轻量、零依赖、一条命令搞定格式化、过滤、提取和转换。装上之后,你很可能就再也回不去手动翻 JSON 的日子了。
安装
几乎所有 Linux 发行版的仓库里都有,一行搞定:
# Debian / Ubuntu
sudo apt install jq -y
# CentOS / Rocky / Fedora
sudo yum install jq -y
# macOS
brew install jq
装完验证一下,有版本号就对了:
jq --version
# jq-1.7.1
实战一:格式化输出,让 JSON 变”好看”
jq 最基本的用法就是一个点 .,表示”把整个 JSON 漂亮地打印出来”:
curl -s https://api.github.com/repos/jqlang/jq | jq .
对比一下不加 jq . 的输出——光一个缩进对齐就值回安装时间了。而且 jq 默认带语法高亮,什么字段名什么值,一眼分清。
实战二:提取指定字段
这才是 jq 真正值钱的能力。比如从 Docker 的容器列表里只看名字和状态:
docker ps --format json | jq '{name: .Names, status: .Status}'
输出类似:
{
"name": "vpnt_wp",
"status": "Up 14 days"
}
{
"name": "vpnt_db",
"status": "Up 14 days"
}
当然也可以取一个字段的值直接输出纯文本,不再包在 JSON 里:
curl -s https://api.github.com/repos/jqlang/jq | jq -r '.stargazers_count'
# 输出:30500(或者某个具体数字)
-r 参数是 raw output,去掉引号,拿到干净的值——写脚本的时候特别有用。
实战三:遍历数组与条件过滤
JSON 里最常见的结构就是数组。jq 用 .[] 遍历每个元素:
# 拿 GitHub 仓库的前 5 个 issue 标题
curl -s https://api.github.com/repos/jqlang/jq/issues | jq '.[] | .title'
还能加条件过滤:找到所有状态为 “open” 且包含 “bug” 的 issue:
curl -s https://api.github.com/repos/jqlang/jq/issues \
| jq '.[] | select(.state == "open" and (.title | test("bug"; "i"))) | .title'
这里 select() 就像 SQL 的 WHERE,test() 支持正则匹配——在终端里做数据筛选,利索得很。
实战四:日志分析——一行命令算 Nginx 状态码分布
如果你把 Nginx 日志转成 JSON 格式(加一条 log_format 配置的事),分析就变成了 jq 专场:
cat access.json.log | jq -r '.status' | sort | uniq -c | sort -rn
要更精准的统计,直接用 jq 内置的 group_by:
cat access.json.log | jq -n '[inputs] | group_by(.status)[] | {status: .[0].status, count: length}'
结果一目了然:哪个状态码最多、哪个接口响应慢,不用装 ELK 也能做基础分析。
实战五:构造新 JSON 数据
jq 不光能读,也能写。从已有数据重新组装成新的 JSON 结构:
curl -s https://api.github.com/repos/jqlang/jq \
| jq '{repo: .full_name, stars: .stargazers_count, language: .language, license: .license.spdx_id}'
输出:
{
"repo": "jqlang/jq",
"stars": 30500,
"language": "C",
"license": "MIT"
}
一行命令就把 GitHub API 返回的几十个字段缩减成自己关心的 4 个,配合 -c(compact 紧凑输出),每条占一行,直接丢给其他命令接着处理——在自动化脚本里就是神器。
一点小建议
jq 的语法远不止这些,map、reduce、管道嵌套、自定义函数…… 说实话学深了跟一门小语言差不多。但别被吓到,我个人的建议是:先记住 jq . 格式化、jq '.key' 取值、jq '.[] | select()' 过滤这三个套路,就已经能覆盖日常 90% 的需求了。碰到复杂的上网搜一下 jq recipes,比硬记快多了。
对了,如果你还在用 Python 的 json.tool 模块做格式化,试试换成 jq——速度更快,功能更强,而且少打几个字符。IT 大叔的精髓就是:能用一个命令解决的,绝不动手写脚本。
相关阅读:如果你对终端效率工具有兴趣,还可以看看 ripgrep(文件搜索)和 bat(带语法高亮的 cat),配合 jq 一起用,终端体验直接从”毛坯房”升级到”精装房”。
