欢迎各位兄弟 发布技术文章
这里的技术是共享的
macos jq 命令详解
jq
(json query)是一个强大的命令行 JSON 处理器,在 macOS(或任何 Unix 系统)中用于解析、过滤、转换和操作 JSON 数据。以下是 jq
的详细用法说明:
macOS 通常未预装 jq
,可通过以下命令安装:
bashbrew install jq # 使用 Homebrew
bashjq [options] <filter> [file.json]
若未指定 file.json
,则从标准输入(stdin)读取数据。
选项 | 作用 |
---|---|
-r
| 输出原始字符串(非 JSON 格式) |
-c
| 紧凑输出(单行 JSON) |
-s
| 将输入合并为数组后处理 |
--arg var v
| 传递变量($var 值为 v ) |
bashjq '.' data.json # 格式化输出整个文件 cat data.json | jq # 通过管道输入
bashjq '.key' data.json # 提取顶级键 jq '.parent.child' data.json # 嵌套提取 jq '.array[0]' data.json # 数组索引 jq '.object[]' data.json # 遍历对象值
bashjq 'select(.age > 30)' data.json # 筛选 age > 30 jq 'map(select(.enabled))' data.json # 过滤数组元素
bashjq '.numbers | length' data.json # 计算数组长度 jq '.prices | add' data.json # 求和 jq '. | max' data.json # 最大值
bashjq '.name = "New Name"' data.json # 修改字段 jq '. + { "newKey": "value" }' data.json # 添加字段 jq '[.users[] | {name}]' data.json # 构造新数组
bashjq '.users[] | .name' data.json # 提取所有用户名 jq '.data | keys' data.json # 获取所有键名
bashjq --arg user "Alice" '.name = $user' data.json
正则匹配:jq 'match("pattern")'
自定义函数:jq 'def add(x,y): x+y; add(1,2)'
错误处理:jq 'try .key catch "default"'
bashjq '.users[].address.city' data.json
bashjq '. | {newName: .oldName}' data.json
bashjq -s '.[0] * .[1]' file1.json file2.json
bashcurl -s https://api.example.com/data | jq '.results[] | {id, name}'
bashjq -r '.name' data.json # 直接输出字符串(无引号) jq -c '.' data.json # 单行紧凑 JSON
使用 debug
函数:jq 'debug | .key' data.json
逐步调试:分步执行管道操作。
掌握 jq
可以高效处理 JSON 数据,尤其在脚本和 API 交互中非常实用。更多功能参考官方手册:
👉 jq Manual
echo '{"name": "John"}' | jq -r '.name' 详解
让我们逐步解析这个命令的执行过程和原理:
bashecho '{"name": "John"}' | jq -r '.name'
部分 | 说明 |
---|---|
echo '{"name": "John"}' | 向标准输出打印一个 JSON 字符串 |
` | ` |
jq -r '.name' | 用 jq 处理 JSON,-r 表示原始输出,.name 是过滤器 |
echo 输出 JSON
bashecho '{"name": "John"}'
输出字符串:{"name": "John"}
(注意:此时只是一个字符串,还不是 JSON 对象)
管道传递到 jq
上一步的字符串通过管道 (|
) 传递给 jq
jq 解析输入
jq
会自动将输入字符串解析为 JSON 对象:
json{ "name": "John" }
应用过滤器 .name
过滤器 .name
表示提取 JSON 中的 name
字段
处理结果:JSON 字符串 "John"
(注意:这是合法的 JSON 字符串,包含双引号)
-r
选项的作用
-r
(raw-output) 会去掉结果中的 JSON 引号,输出纯文本
最终输出:John
(没有引号)
-r
的输出命令 | 输出 | 说明 |
---|---|---|
`echo '{"name": "John"}' | jq '.name'` | "John" |
`echo '{"name": "John"}' | jq -r '.name'` | John |
赋值给 Shell 变量
bashname=$(echo '{"name": "John"}' | jq -r '.name') echo "Hello, $name!" # 输出:Hello, John!
直接处理非 JSON 系统
bash# 将结果传递给需要纯文本的命令 echo '{"name": "John"}' | jq -r '.name' | grep "John"
生成配置文件
bashecho '{"port": 8080}' | jq -r '.port' > config.port
字段不存在时
bashecho '{"age": 30}' | jq -r '.name'
输出:null
(不会报错)
解决方法:用 //
设置默认值
bashecho '{"age": 30}' | jq -r '.name // "unknown"'
输入非 JSON 时
bashecho "Not JSON" | jq '.name'
会报错:parse error: Invalid numeric literal
解决方法:先验证输入
bashecho $data | jq -e '. 2>/dev/null || echo "Invalid JSON"
嵌套对象提取
bashecho '{"user": {"name": "John"}}' | jq -r '.user.name'
数组处理
bashecho '{"names": ["John", "Alice"]}' | jq -r '.names[]'
这个简单的 jq
命令组合是处理 JSON 的基础操作,理解了它就能举一反三处理更复杂的场景。