I have a json file list_values.json with array of json with an "origine" field :
[
{
"origine": "reason1",
"identifiant": "1234_AAA"
},
{
"origine": "reason3",
"identifiant": "5678_BBB"
}
]
I have mapping.json file with a list of predefined fields :
{
"REASON_0": "reason0",
"REASON_1": "reason1",
"REASON_2": "reason2",
"REASON_3": "reason3",
"REASON_4": "reason4"
}
I wrote a bash script using jq with this line :
jq '.[] |= . + {"type": (.identifiant | split("_") | .[1] )}' list_values.json > add_fields.json
My file add_fields.json :
[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB"
}
]
I would like to add a "reason" field equal to the key of mapping.json whose value matches the "origine" field of list_values.json. Like this :
[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA",
"reason": "REASON_1"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB",
"reason": "REASON_3"
}
]
What can I do this with jq ?
I specify that the values of mapping.json are unique as the keys.
The following looks understandable and extensible: it first builds a lookup object (with INDEX) and then maps each input object to a new object with the added properties:
jq 'INDEX(input|to_entries[]; .value) as $mapping
| map(
.type=(.identifiant/"_"|last)
| .reason=$mapping[.origine].key
)' list_values.json mapping.json
Alternatively, merge an object with the new properties into the existing items of the array:
jq 'INDEX(input|to_entries[]; .value) as $mapping
| .[]
|= . + {
type: (.identifiant / "_" | last),
reason: $mapping[.origine].key
}' list_values.json mapping.json
Output:
[
{
"origine": "reason1",
"identifiant": "1234_AAA",
"type": "AAA",
"reason": "REASON_1"
},
{
"origine": "reason3",
"identifiant": "5678_BBB",
"type": "BBB",
"reason": "REASON_3"
}
]
With jq 1.6+ you can use JOIN to get the matchings. To this end, you need to flip keys and values for the index (in the mappings object). In doing so, you can already insert the "reason" field name, which makes it easier to just add the results afterwards:
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"
}
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With