如何使用jq从父元素为子元素的指定属性赋值?
问题描述
给定1Password .1pux 导出格式的JSON数据:
{ "accounts": [ { "attrs": { "name": "One" }, "vaults": [ { "attrs": {"name": "Private", "type": "P"}, "items": [ { "foo": "001", "overview": {"subtitle": "foo"} }, { "foo": "002", "overview": {"subtitle": "foo", "tags": ["a tag"]} } ] }, { "attrs": {"name": "Public", "type": "P"}, "items": [ { "foo": "001", "overview": {"subtitle": "foo"} }, { "foo": "002", "overview": {"subtitle": "foo", "tags": ["a tag"]} } ] } ] } ] }
需求:对每个 .accounts[].vaults[].items[] 元素,创建或替换其 overview.tags 字段为 [父级vault的attrs.name](即当前item所属vault的名称),得到目标输出。
优雅的jq实现
核心命令
jq ' .accounts[].vaults[] |= ( . as $vault | .items[] |= (.overview.tags = [$vault.attrs.name]) ) ' input.json
思路拆解
- 先定位到所有vault节点:用
.accounts[].vaults[]遍历每个vault,|=操作符负责直接修改原对象,保证整个JSON结构完整,只改动目标字段。 - 保存当前vault上下文:用
. as $vault把当前vault的完整对象存为变量,后续处理items时可以直接引用vault名称,避免反复回溯层级,代码更清晰。 - 批量修改items:遍历当前vault下的所有
.items[],同样用|=修改每个item,直接给.overview.tags赋值为包含vault名称的数组——不管原item有没有tags字段,都会被覆盖或创建,完美匹配需求。
紧凑简化版(可选)
如果偏好更简洁的写法,可以利用jq的作用域特性省略变量,外层的 .attrs.name 会自动指向当前vault的属性:
jq '.accounts[].vaults[] |= (.items[] |= (.overview.tags = [.attrs.name]))' input.json
内容的提问来源于Stack Exchange,提问作者Ken Williams
相关产品推荐
相关产品推荐

