我有两个JSON文件a.json
和b.json
。 a.json文件中的内容是一个JSON对象,b.json中的内容是一个数组。我想通过从b中检索值来在a.json中的每个status
中添加/更新mappings
字段。 json文件。
a.json:
{
"title": 25886,
"data": {
"request": {
"c": 46369,
"t1": 1562050127.376641
},
},
"rs": {
"mappings": {
"12345": {
"id": "12345",
"name": "test",
"customer_id": "11228",
},
"45678": {
"id": "45678",
"name": "abc",
"customer_id": "11206",
}
}
}}
b.json:
[
{
"status": "pending",
"extra": {
"name": "test"
},
"enabled": true,
"id": "12345"
},
{
"status": "not_started",
"extra": {
"name": "abc"
},
"enabled": true,
"id": "45678"
}
]
以下是我的预期输出:
{
"title": 25886,
"data": {
"request": {
"c": 46369,
"t1": 1562050127.376641
},
},
"rs": {
"mappings": {
"12345": {
"id": "12345",
"name": "test",
"customer_id": "11228",
"status":"pending"
},
"45678": {
"id": "45678",
"name": "abc",
"customer_id": "11206",
"status":"not_started"
}
}
}}
在这个预期的JSON文件中,我们有status
字段,该字段的值基于匹配的id
值从b.json文件中检索。如何使用jq
来做到这一点?
答案 0 :(得分:0)
出于这个问题的目的,b.json本质上定义了一个字典,因此为了简单,高效甚至优雅起见,
首先,请使用内置函数INDEX
创建相关的字典:
INDEX( $b[] | {id, status}; .id )
这假设调用jq的方式如下:
jq --argfile b b.json -f update.jq a.json
(是的,我知道--argfile
已被弃用。请随意选择另一种将$ b设置为b.json内容的方法。)
现在,要执行更新,最简单的方法是将{update}运算符|=
与map_values
结合使用。 (随时查看jq手册:-)
将所有内容放在一起:
INDEX( $b[] | {id, status}; .id ) as $dict
| .rs.mappings |= map_values( .status = $dict[.id].status )
答案 1 :(得分:0)
使用基于步行路径的unix实用程序 jtc
:
bash $ <a.json jtc -w'<id>l:<ID>v[-1]' -i b.json -i'<ID>s[-1][status]'
{
"data": {
"request": {
"c": 46369,
"t1": 1562050127.376641
}
},
"rs": {
"mappings": {
"12345": {
"customer_id": "11228",
"id": "12345",
"name": "test",
"status": "pending"
},
"45678": {
"customer_id": "11206",
"id": "45678",
"name": "abc",
"status": "not_started"
}
}
},
"title": 25886
}
bash $
-w
,要插入新记录的地方)递归查找每个标签id
(<id>l:
),并在命名空间ID
中存储条目(<ID>v
)并后退1级,以指向父条目-w
),都会有一个相应的插入遍历(第二个-i
,第一个指向用于插入的源文件);插入遍历将找到(在b.json
中)存储在名称空间ID
中的值,提升一级并选择status
记录,将其插入 PS>披露:我是jtc
-用于JSON操作的shell cli工具的创建者