Reputation: 410
I am trying to merge the following two json files; but I only seem to be able to partially merge; as soon as an element is within an array the reduce fails.
{
"value1": 200,
"timestamp": 1382461861,
"deployment": [
{
"component": "whatever",
"containers": "key value"
}
]
}
and
{
"status": 200,
"timestamp": 1382461861,
"deployment": [
{
"autoscaling": {
"maxReplicas": 1,
"minReplicas": 1,
"targetCPUUtilizationPercentage": 40
}
}
]
}
Using jq -s 'reduce .[] as $item({}; . * $item)' x.json x2.json
does not work if the input is an array; instead I get a partial merge but not a deep merge
{
"value1": 200,
"timestamp": 1382461861,
"deployment": [
{
"autoscaling": {
"maxReplicas": 1,
"minReplicas": 1,
"targetCPUUtilizationPercentage": 40
}
}
],
"status": 200
}
The expected output would be
{
"value1": 200,
"timestamp": 1382461861,
"deployment": [
{
"component": "whatever",
"containers": "key value",
"autoscaling": {
"maxReplicas": 1,
"minReplicas": 1,
"targetCPUUtilizationPercentage": 40
}
}
],
"status": 200,
}
Can i anyone suggest where I may be going wrong
Upvotes: 1
Views: 293
Reputation: 116870
It looks like you will have to define your own "merge" filter.
Given your sample inputs, the following does produce the result you ask for, but it should probably be taken as a starting point as you refine your specification:
def merge($a; $b):
if ($a|type) == "object" and ($b|type) == "object"
then reduce (($a + $b)|keys_unsorted[]) as $k ({};
.[$k] = merge($a[$k]; $b[$k]))
elif ($a|type) =="array" and ($b|type) == "array" then $a + $b | add
elif $b == null then $a
else $b
end;
For efficiency, you might wish to consider invoking this as merge(input;input)
, using the -n command-line option instead of -s.
Upvotes: 2