简介
下面这份文档适合作为技术博客文章,覆盖了 jq 从入门到实战的大部分常用场景,并且尽量结合 DevOps、区块链节点运维、日志分析等实际工作场景。
jq 完全教程:JSON 处理神器从入门到实战
什么是 jq
jq 是 Linux/macOS 下最强大的 JSON 命令行处理工具。
如果说:
- grep 处理文本
- awk 处理表格
- sed 处理字符串
那么:
jq 就是专门处理 JSON 的神器。
官方网站:
安装:
macOS
brew install jq
Ubuntu
sudo apt install jq
CentOS
yum install jq
验证:
jq –version
输出:
jq-1.7
⸻
为什么要学习 jq
现代开发中到处都是 JSON:
- REST API
- Kubernetes
- Docker
- Prometheus
- Ethereum RPC
- Solana RPC
- Elasticsearch
- Cloudflare API
例如:
{
“jsonrpc”:”2.0”,
“id”:1,
“result”:”0x1d4c”
}
不用 jq:
curl xxx
输出一坨:
{“jsonrpc”:”2.0”,”id”:1,”result”:”0x1d4c”}
使用 jq:
curl xxx | jq
变成:
{
“jsonrpc”: “2.0”,
“id”: 1,
“result”: “0x1d4c”
}
瞬间舒服。
⸻
基本语法
jq 的基本形式:
jq ‘
例如:
cat data.json | jq ‘.’
表示:
输出整个 JSON
⸻
读取字段
假设:
{
“name”:”Tom”,
“age”:18
}
读取:
jq ‘.name’
输出:
“Tom”
读取年龄:
jq ‘.age’
输出:
18
⸻
去掉双引号
默认:
jq ‘.name’
输出:
“Tom”
很多脚本不方便。
使用:
jq -r ‘.name’
输出:
Tom
-r
表示:
raw output
这是最常用参数之一。
⸻
多层 JSON
例如:
{
“user”: {
“name”: “Tom”,
“age”: 18
}
}
读取:
jq ‘.user.name’
输出:
“Tom”
⸻
数组操作
JSON:
{
“users”: [
{“name”:”Tom”},
{“name”:”Jack”},
{“name”:”Lucy”}
]
}
读取第一个:
jq ‘.users[0]’
输出:
{
“name”:”Tom”
}
读取名称:
jq ‘.users[0].name’
输出:
“Tom”
⸻
遍历数组
例如:
jq ‘.users[]’
输出:
{
“name”:”Tom”
}
{
“name”:”Jack”
}
{
“name”:”Lucy”
}
只输出名称:
jq -r ‘.users[].name’
输出:
Tom
Jack
Lucy
⸻
数组长度
jq ‘.users | length’
输出:
3
⸻
获取最后一个元素
jq ‘.users[-1]’
输出:
{
“name”:”Lucy”
}
⸻
条件过滤
数据:
[
{“name”:”Tom”,”age”:18},
{“name”:”Jack”,”age”:25},
{“name”:”Lucy”,”age”:30}
]
筛选:
jq ‘.[] | select(.age > 20)’
输出:
{
“name”:”Jack”,
“age”:25
}
{
“name”:”Lucy”,
“age”:30
}
⸻
多条件过滤
jq ‘.[] | select(.age > 20 and .age < 30)’
输出:
{
“name”:”Jack”,
“age”:25
}
⸻
字段存在判断
jq ‘has(“name”)’
输出:
true
⸻
提取多个字段
例如:
{
“name”:”Tom”,
“age”:18,
“city”:”Shanghai”
}
输出:
jq ‘{name,age}’
结果:
{
“name”:”Tom”,
“age”:18
}
⸻
重命名字段
jq ‘{username:.name,userage:.age}’
输出:
{
“username”:”Tom”,
“userage”:18
}
⸻
修改字段
原始:
{
“name”:”Tom”,
“age”:18
}
修改:
jq ‘.age=20’
输出:
{
“name”:”Tom”,
“age”:20
}
⸻
删除字段
jq ‘del(.age)’
结果:
{
“name”:”Tom”
}
⸻
排序
数据:
[
{“name”:”Tom”,”age”:30},
{“name”:”Jack”,”age”:18},
{“name”:”Lucy”,”age”:25}
]
按年龄:
jq ‘sort_by(.age)’
结果:
[
{
“name”:”Jack”,
“age”:18
},
{
“name”:”Lucy”,
“age”:25
},
{
“name”:”Tom”,
“age”:30
}
]
⸻
统计
求和:
jq ‘[.[].age] | add’
输出:
73
平均值:
jq ‘[.[].age] | add / length’
输出:
24.333333333333332
⸻
map
提取所有名称:
jq ‘map(.name)’
结果:
[
“Tom”,
“Jack”,
“Lucy”
]
⸻
实战:调用 RPC
获取区块高度:
curl -s
-H “Content-Type: application/json”
-d ‘{“jsonrpc”:”2.0”,”id”:1,”method”:”eth_blockNumber”,”params”:[]}’
https://rpc.consciousnesschain.com
| jq -r ‘.result’
输出:
0x1d4c
转换十进制:
curl … | jq -r ‘.result’ | xargs printf “%d\n”
⸻
实战:Docker
查看容器名称:
docker inspect container_id | jq ‘.[0].Name’
去掉双引号:
docker inspect container_id | jq -r ‘.[0].Name’
⸻
实战:Kubernetes
获取 Pod 名称:
kubectl get pods -o json
| jq -r ‘.items[].metadata.name’
获取所有镜像:
kubectl get pods -o json
| jq -r ‘.items[].spec.containers[].image’
⸻
实战:Prometheus
查询结果:
{
“status”:”success”,
“data”:{
“result”:[
{
“value”:[
1749700000,
“123”
]
}
]
}
}
获取指标值:
jq -r ‘.data.result[0].value[1]’
输出:
123
⸻
实战:日志分析
统计所有错误级别:
日志:
{“level”:”info”}
{“level”:”error”}
{“level”:”warn”}
{“level”:”error”}
统计:
jq -r ‘.level’ log.json
| sort
| uniq -c
输出:
2 error
1 info
1 warn
⸻
实战:调用 REST API
获取 GitHub 用户信息:
curl -s https://api.github.com/users/torvalds | jq
输出:
{
“login”: “torvalds”,
“id”: 1024025,
…
}
获取用户名:
curl -s https://api.github.com/users/torvalds
| jq -r ‘.login’
输出:
torvalds
获取仓库数量:
curl -s https://api.github.com/users/torvalds
| jq ‘.public_repos’
⸻
实战:Docker
查看容器名称:
docker inspect nginx
| jq -r ‘.[0].Name’
查看 IP:
docker inspect nginx
| jq -r ‘.[0].NetworkSettings.IPAddress’
查看挂载目录:
docker inspect nginx
| jq ‘.[0].Mounts’
⸻
实战:Kubernetes
查看所有 Pod:
kubectl get pods -o json
| jq -r ‘.items[].metadata.name’
查看所有镜像:
kubectl get pods -o json
| jq -r ‘.items[].spec.containers[].image’
查看 Pod 状态:
kubectl get pods -o json
| jq -r ‘.items[] | [.metadata.name,.status.phase] | @tsv’
输出:
api-server Running
mysql Running
redis Pending
⸻
实战:Prometheus
查询指标:
curl -s http://localhost:9090/api/v1/query
–data-urlencode ‘query=up’
| jq
获取指标值:
jq -r ‘.data.result[].value[1]’
⸻
实战:Nginx JSON 日志
日志:
{
“remote_addr”:”10.0.0.1”,
“status”:200,
“request_time”:0.023
}
筛选慢请求:
jq ‘select(.request_time > 1)’
筛选错误请求:
jq ‘select(.status >= 500)’
⸻
实战:统计日志等级
日志:
{“level”:”info”}
{“level”:”error”}
{“level”:”warn”}
{“level”:”error”}
统计:
jq -r ‘.level’ app.log
| sort
| uniq -c
输出:
2 error
1 info
1 warn
⸻
实战:配置文件检查
config.json:
{
“server”: {
“host”:”127.0.0.1”,
“port”:8080
}
}
查看端口:
jq ‘.server.port’ config.json
查看主机:
jq -r ‘.server.host’ config.json
⸻
实战:JSON 格式化工具
压缩:
jq -c .
输出:
{“name”:”Tom”,”age”:18}
美化:
jq .
输出:
{
“name”: “Tom”,
“age”: 18
}
⸻
实战:CSV 转换
JSON:
[
{“name”:”Tom”,”age”:18},
{“name”:”Jack”,”age”:20}
]
转换:
jq -r ‘.[] | [.name,.age] | @csv’
输出:
“Tom”,18
“Jack”,20
⸻
实战:生成 TSV
jq -r ‘.[] | [.name,.age] | @tsv’
输出:
Tom 18
Jack 20
⸻
总结
把最后一章改成:
jq 几乎会出现在所有现代基础设施中:
- REST API
- Docker
- Kubernetes
- Prometheus
- Elasticsearch
- Loki
- Nginx JSON 日志
- GitHub API
- GitLab API
- 各类配置文件
学会 jq 后,可以大幅提升 Linux 命令行处理 JSON 的效率。