用jq和bash脚本映射两个json



我有一个json文件list_values。Json带有"origin "字段:

[
{
"origine": "reason1",
"identifiant": "1234_AAA"
},
{
"origine": "reason3",
"identifiant": "5678_BBB"
}
]

我有映射。带有预定义字段列表的Json文件:

{
"REASON_0": "reason0",
"REASON_1": "reason1",
"REASON_2": "reason2",
"REASON_3": "reason3",
"REASON_4": "reason4"
}

我用jq写了一个bash脚本,下面是这一行:

jq '.[] |= . + {"type": (.identifiant | split("_") | .[1] )}' list_values.json > add_fields.json

我的文件add_fields。json:

[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB"
}
]

我想添加一个"原因"。字段等于映射的键。Json,其值与"origin "list_values.json字段。像这样:

[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA",
"reason": "REASON_1"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB",
"reason": "REASON_3"
}
]

我可以用jq做什么?

我指定映射的值。Json作为键是唯一的。

下面的代码看起来是可以理解和扩展的:它首先构建一个查找对象(使用INDEX),然后将每个输入对象映射到一个具有添加属性的新对象:

jq 'INDEX(input|to_entries[]; .value) as $mapping
| map(
.type=(.identifiant/"_"|last)
| .reason=$mapping[.origine].key
)' list_values.json mapping.json

或者,将具有新属性的对象合并到数组的现有项中:

jq 'INDEX(input|to_entries[]; .value) as $mapping
| .[]
|= . + {
type: (.identifiant / "_" | last),
reason: $mapping[.origine].key
}' list_values.json mapping.json

输出:

[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA",
"reason": "REASON_1"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB",
"reason": "REASON_3"
}
]

使用jq 1.6+,您可以使用JOIN来获得匹配。为此,您需要翻转索引的键和值(在映射对象中)。在这样做的过程中,您已经可以插入"reason"字段名,这使得之后只add结果变得更容易:

jq '[JOIN(
input | with_entries({key: .value, value: {reason: .key}});
.[] | .type = (.identifiant | split("_")[1]);
.origine;
add
)]' list_values.json mapping.json
[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA",
"reason": "REASON_1"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB",
"reason": "REASON_3"
}
]