I have the following json files:
File1:
[
{
"id": 1,
"name": "serviceName",
"owner": {
"id": 1,
"name": "Nicole"
}
}
]
and File2:
[
{
"id": 1,
"name": "Nicole",
"email": "[email protected]"
}
]
I would like to have them merged like this:
[
{
"id": 1,
"name": "serviceName",
"owner": {
"id": 1,
"name": "Nicole",
"email": "[email protected]"
}
}
]
I'm trying the approach from here and try to use the following:
jq --argfile new file2.json '
($new | INDEX(.ID)) as $dict
| .owner
|= (if $dict[.ID] then . $dict[.ID] else . end)
' file1.json
But that just results in an error.
Can anyone maybe provide me with some tips?
CodePudding user response:
Your approach fails because of the followings:
- Field names are case-sensitive. Having
{"id": 1}
, use.id
, not.ID
. - Field names are strings. Having
{"id": 1}
andINDEX(.id) as $dict
, use$dict[.id | tostring]
or$dict[.id | @text]
or$dict["\(.id)"]
to convert the number1
into the string"1"
in the object index. - Your files contain arrays. While
INDEX
defaults to read.[]
fromfile2.json
, you need to do it forfile1.json
yourself.
jq --argfile new file2.json '
($new | INDEX(.id)) as $dict | .[].owner |= (
if $dict[.id | @text] then . $dict[.id | @text] else . end
)
' file1.json
[
{
"id": 1,
"name": "serviceName",
"owner": {
"id": 1,
"name": "Nicole",
"email": "[email protected]"
}
}
]
As a suggestion, you could also employ JOIN
to merge on a given key:
jq '
JOIN(
INDEX(input[]; .id); .[]; .id | @text; .[0].owner = .[1] | .[0]
)
' file1.json file2.json
[
{
"id": 1,
"name": "serviceName",
"owner": {
"id": 1,
"name": "Nicole",
"email": "[email protected]"
}
}
]