一文jq:如何轻松转换JSON对象
在现代软件开发和数据处理的日常工作中,JSON(JavaScript Object Notation)已经成为数据交换的事实标准,无论是处理API响应、配置文件还是日志数据,我们经常需要与JSON格式的数据打交道,当数据变得复杂时,手动解析和修改JSON不仅低效,而且容易出错,这时,一个强大的命令行工具——jq——就成为了开发者的得力助手。
本文将浅出地介绍如何使用 jq 来转换JSON对象,让你从繁琐的数据处理中解放出来。
什么是jq?
jq 是一个轻量级、灵活的命令行JSON处理器,它就像为JSON数据设计的 sed 或 awk,但语法更接近于JavaScript,你可以通过 jq 来解析、过滤、映射和转换JSON数据,并将结果以美观的格式重新输出。
安装jq:
在开始之前,请确保你已经安装了 jq,大多数Linux和macOS系统可以通过包管理器轻松安装:
# 对于 Debian/Ubuntu sudo apt-get install jq # 对于 macOS (使用 Homebrew) brew install jq
核心概念:从输入到输出
jq 的基本工作模式是:从标准输入读取JSON数据,通过你提供的“过滤器”进行处理,然后将结果输出到标准输出。
一个简单的 jq 命令结构如下:
jq '过滤器' your_file.json
或者通过管道符传递数据:
cat your_file.json | jq '过滤器'
jq怎么转换JSON对象?核心技巧
转换JSON对象是 jq 最核心的功能,下面我们通过一系列从简单到复杂的例子,来它的使用方法。
基础选择:提取单个值
转换的第一步是选择你想要操作的数据,使用点 来表示整个输入对象。
示例JSON (data.json):
{
"name": "张三",
"age": 30,
"city": "北京",
"isStudent": false
}
命令:
jq '.' data.json
输出: (这实际上是美化输出,但展示了 的用法)
{
"name": "张三",
"age": 30,
"city": "北京",
"isStudent": false
}
要提取特定字段的值,只需在点后面加上字段名(用引号括起来)。
命令:
jq '.name' data.json
输出:
"张三"
组合选择:访问嵌套对象
JSON对象可以嵌套。jq 使用点号 来逐层访问。
示例JSON (nested.json):
{
"user": {
"id": 123,
"contact": {
"email": "zhangsan@example.com",
"phone": "13800138000"
}
},
"status": "active"
}
命令:
jq '.user.contact.email' nested.json
输出:
"zhangsan@example.com"
创建新对象: 语法
这是转换JSON对象最强大的功能之一,你可以通过 语法从现有数据构建一个全新的对象。
示例:
从 data.json 中,我们只想提取 name 和 city,并创建一个新的对象。
命令:
jq '{newName: .name, location: .city}' data.json
输出:
{
"newName": "张三",
"location": "北京"
}
这里,newName 和 location 是你为新对象创建的字段名,而 .name 和 .city 则表示从原始对象中获取对应的值。
处理数组:.[]
当你的JSON值是一个数组时,.[] 操作符会“解压”这个数组,对其中每一个元素都应用后面的过滤器。
示例JSON (users.json):
[
{"name": "张三", "role": "admin"},
{"name": "李四", "role": "editor"},
{"name": "王五", "role": "viewer"}
]
命令:
jq '.[].name' users.json
输出:
"张三" "李四" "王五"
你也可以结合对象创建语法,为每个用户生成一个简化的信息卡片。
命令:
jq '.[] | {displayName: .name, accessLevel: .role}' users.json
输出:
{
"displayName": "张三",
"accessLevel": "admin"
}
{
"displayName": "李四",
"accessLevel": "editor"
}
{
"displayName": "王五",
"accessLevel": "viewer"
}
这里的管道符 表示将前一个表达式的输出作为后一个表达式的输入。
条件转换:if-then-else
jq 支持条件逻辑,让你可以根据数据的不同值进行不同的转换。
示例: 根据用户的角色,返回一个友好的中文描述。
命令:
jq '.[] | .name + " 的角色是 " + ( if .role == "admin" then "管理员" elif .role == "editor" then "编辑者" else "访客" end )' users.json
输出:
"张三 的角色是 管理员" "李四 的角色是 编辑者" "王五 的角色是 访客"
注意: 在 jq 中用于字符串连接。
数据类型转换与计算
jq 也可以进行简单的计算和类型转换。
示例:
假设 data.json 中有一个 price 字段,我们想打九折并四舍五入到整数。
示例JSON (product.json):
{
"product": "超级键盘",
"price": 158.50
}
命令:
jq '{product: .product, finalPrice: (.price * 0.9 | round)}' product.json
输出:
{
"product": "超级键盘",
"finalPrice": 143
}
这里,(.price * 0.9 | round) 是一个复合表达式,先计算 price * 0.9,然后将结果通过管道 传递给 round 函数进行四舍五入。
高级技巧:使用 map 和 with_entries
map(f): 对数组的每个元素应用过滤器f,并返回一个新数组,它和.[] | ...的区别在于,map会将结果重新组合成一个数组。with_entries(f): 对对象的每个键值对应用过滤器f,非常适合批量修改对象的所有字段。
示例 (map):
给 users.json 中的每个用户都添加一个 status: "active" 字段。
命令:
jq '.[] | . + {status: "active"}' users.json
输出:
{
"name": "张三",
"role": "admin",
"status": "active"
}
{
"name": "李四",
"role": "editor",
"status": "active"
}
...
使用 map 可以得到一个包含所有新用户对象的数组:
jq 'map(. + {status: "active"})' users.json
示例 (with_entries):
将 data.json 中所有字段的键名都转换为大写。
命令:
jq 'with_entries(.key |= ascii_upcase)' data.json
输出:
{
"NAME": "张三",
"AGE": 30,
"CITY": "北京",
"ISSTUDENT": false
}
这里 是一个赋值操作符,表示将右边的表达式结果赋给左边的路径。
jq 是一个功能极其强大的工具,它能让你在处理JSON数据时如虎添翼,我们今天学习的关键转换技巧包括:
- 选择数据: 和
.field - 构建新对象:
{newKey: .oldField} - 遍历数组:
.[]和map(...) - 条件逻辑:
if-then-else-end - 批量处理:
with_entries(...)
从简单的字段提取到复杂的数据重塑,jq 提供了一套优雅而高效的解决方案,希望这篇文章能



还没有评论,来说两句吧...