Linux jq 命令实战:JSON 数据提取、筛选与转换
前言
在 Linux 服务器运维中,经常需要通过 API 获取服务器状态、配置信息或者监控数据。这些接口通常返回 JSON 格式的内容,如果直接在终端查看,数据较多时不容易找到需要的信息。
例如,一个接口可能返回几十台服务器的名称、IP 地址、地区和运行状态,但实际只想提取其中的公网 IP,或者筛选出正在运行的实例。
如果使用 grep、sed 等文本工具处理 JSON,不仅命令容易变得复杂,还可能因为数据结构变化而出现匹配错误。
jq 就是一个专门处理 JSON 数据的命令行工具,可以方便地提取字段、筛选数组、组合数据和生成新的 JSON。
一、安装 jq
Ubuntu 和 Debian 系统可以使用:
sudo apt update
sudo apt install -y jq
Alpine Linux 可以使用:
apk add jq
安装完成后查看版本:
jq --version
如果已经安装,可以直接开始使用。
二、查看和格式化 JSON
假设有一个服务器信息文件 servers.json:
{
"code": 0,
"data": {
"name": "my-server",
"region": "cn-hongkong",
"status": "running",
"public_ip": "192.0.2.10"
}
}
首先可以使用最简单的命令:
jq '.' servers.json
这里的 . 表示输出整个输入对象。
jq 默认会对 JSON 进行格式化,因此即使原始数据只有一行,也能整理成便于阅读的结构。
如果只想检查 JSON 格式是否正确,可以执行:
jq empty servers.json
如果文件是合法 JSON,命令会正常退出且不输出内容;如果格式错误,则会显示解析错误。
三、提取指定字段
实际使用中,最常见的需求就是提取某个字段。
例如,只需要服务器名称:
jq '.data.name' servers.json
输出:
"my-server"
如果想提取公网 IP:
jq '.data.public_ip' servers.json
默认情况下,jq 会按照 JSON 格式输出字符串,因此结果带有双引号。
如果希望得到纯文本,可以增加 -r:
jq -r '.data.public_ip' servers.json
输出:
192.0.2.10
-r 就是 Raw Output,适合将提取结果交给 Shell 变量或其他命令使用。
如果字段嵌套比较深,也可以通过点号逐级访问:
jq '.data.server.network.ipv4' response.json
如果字段名称包含特殊字符,还可以使用方括号形式访问:
jq '.data["server-name"]' response.json
四、处理 JSON 数组
API 经常会返回多个资源组成的数组。
例如:
{
"data": {
"servers": [
{
"name": "hk-server",
"status": "running",
"cpu": 2
},
{
"name": "bj-server",
"status": "stopped",
"cpu": 4
},
{
"name": "us-server",
"status": "running",
"cpu": 8
}
]
}
}
如果想遍历所有服务器,可以使用 []:
jq '.data.servers[]' servers.json
如果只想获取服务器名称:
jq -r '.data.servers[].name' servers.json
输出:
hk-server
bj-server
us-server
如果希望同时输出名称、状态和 CPU 配置,可以重新组合字段:
jq '.data.servers[] | {
name,
status,
cpu
}' servers.json
这样每台服务器都会生成一个只包含指定字段的新对象。
五、使用 select 筛选数据
如果只想找出正在运行的服务器,可以使用 select():
jq '.data.servers[] | select(.status == "running")' servers.json
select() 会根据条件判断是否保留当前对象。
例如,只需要 CPU 大于等于 4 的服务器:
jq '.data.servers[] | select(.cpu >= 4)' servers.json
也可以组合多个条件:
jq '.data.servers[] |
select(.status == "running" and .cpu >= 4)' servers.json
如果希望保留筛选结果为一个完整数组,而不是逐个输出对象,可以使用 map():
jq '.data.servers |
map(select(.status == "running"))' servers.json
这种方式适合后续还需要继续处理筛选结果的场景。
六、统计数组数量
有时候并不需要查看具体内容,只需要知道符合条件的资源数量。
例如,统计服务器总数:
jq '.data.servers | length' servers.json
统计正在运行的服务器数量:
jq '[.data.servers[] |
select(.status == "running")] | length' servers.json
这里的 length 可以获取数组、字符串等数据的长度。
还可以直接统计不同状态的资源数量,帮助快速了解服务器运行情况。
七、把 JSON 转换为表格数据
如果需要将 API 数据交给 Shell 脚本或者其他程序处理,可以使用 @tsv 输出制表符分隔的数据。
例如:
jq -r '.data.servers[] |
[.name, .status, (.cpu | tostring)] |
@tsv' servers.json
输出类似:
hk-server running 2
bj-server stopped 4
us-server running 8
这种格式可以方便地交给 awk、cut 等工具继续处理,也适合导入电子表格。
如果希望每个 JSON 对象保持在一行,可以使用 -c:
jq -c '.data.servers[]' servers.json
这在生成 JSON Lines 风格的数据时比较方便。
八、在 Shell 脚本中使用 jq
jq 不仅可以手动执行,也很适合放进自动化脚本。
例如:
#!/bin/bash
API_URL="https://example.com/api/servers"
response=$(curl -fsS "$API_URL")
echo "$response" |
jq -r '.data.servers[] |
select(.status == "running") |
.name'
这里使用 curl 获取 API 返回的数据,再交给 jq 筛选运行中的服务器名称。
如果需要通过 Shell 变量传递查询条件,可以使用 --arg:
TARGET="hk-server"
jq --arg name "$TARGET" \
'.data.servers[] | select(.name == $name)' \
servers.json
--arg 会将传入的值作为字符串交给 jq 使用,不需要自己拼接 JSON 字符串。
如果传入的是数字或其他 JSON 类型,可以使用 --argjson。
例如:
MIN_CPU=4
jq --argjson cpu "$MIN_CPU" \
'.data.servers[] | select(.cpu >= $cpu)' \
servers.json
这样就可以根据脚本中的参数动态调整筛选条件。
九、检查 API 返回结果是否符合预期
自动化脚本中,不能只判断 jq 有没有输出,还应该检查关键字段是否满足要求。
例如:
jq -e '.code == 0' servers.json
-e 会根据最后一个输出结果调整程序退出状态。
当表达式结果为 true 时,退出状态为 0;结果为 false 或 null 时,退出状态为非零。
因此可以在 Shell 中使用:
if jq -e '.code == 0' servers.json >/dev/null; then
echo "API 请求成功"
else
echo "API 返回异常"
fi
这种方式适合自动化任务中检查接口返回的业务状态。
需要注意,HTTP 请求成功不代表 API 业务处理一定成功。例如服务器返回 HTTP 200,但 JSON 中的业务状态码仍然可能表示失败。
另外,如果接口返回的数据不是合法 JSON,jq 也会解析失败。因此实际使用时应同时处理 curl 的网络错误和 jq 的解析错误。
十、几个常用参数总结
| 参数 | 作用 |
|---|---|
. |
输出完整 JSON |
-r |
字符串原样输出 |
-c |
压缩为单行 JSON |
-e |
根据结果设置退出状态 |
-s |
将所有输入读取为一个数组 |
-n |
不读取输入,直接执行表达式 |
--arg |
向 jq 传递字符串变量 |
--argjson |
向 jq 传递 JSON 类型变量 |
需要注意,jq 的过滤表达式也有自己的语法,Shell 本身同样会解析引号和特殊字符。在 Linux Shell 中,通常建议使用单引号包裹 jq 表达式,减少不必要的转义。
总结
jq 是 Linux 环境中非常实用的 JSON 处理工具,尤其适合 API 调用、自动化脚本和服务器管理。
日常使用时,可以先掌握几个核心操作:
- 使用
.格式化和查看 JSON。 - 使用点号提取嵌套字段。
- 使用
[]遍历数组。 - 使用
select()筛选数据。 - 使用
map()组合处理结果。 - 使用
-r输出纯文本。 - 使用
--arg将 Shell 参数传入 jq。
相比直接使用 grep 和 sed 处理 JSON,jq 能够按照数据结构进行操作,减少格式变化带来的问题。
如果经常需要通过 API 管理服务器或处理监控数据,熟悉 jq 可以让很多原本复杂的文本处理任务变得简单。
- 点赞
- 收藏
- 关注作者
评论(0)