Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge 2 JSON objects from 2 files using jq?

I'm using the jq tools (jq-json-processor) in shell script to parse json.

I've got 2 json files and want to merge them into one unique file

Here the content of files:

file1

{     "value1": 200,     "timestamp": 1382461861,     "value": {         "aaa": {             "value1": "v1",             "value2": "v2"         },         "bbb": {             "value1": "v1",             "value2": "v2"         },         "ccc": {             "value1": "v1",             "value2": "v2"         }     } } 

file2

{     "status": 200,     "timestamp": 1382461861,     "value": {         "aaa": {             "value3": "v3",             "value4": 4         },         "bbb": {             "value3": "v3"         },               "ddd": {             "value3": "v3",             "value4": 4         }     } } 

expected result

{     "value": {         "aaa": {             "value1": "v1",             "value2": "v2",             "value3": "v3",             "value4": 4         },         "bbb": {             "value1": "v1",             "value2": "v2",             "value3": "v3"         },         "ccc": {             "value1": "v1",             "value2": "v2"         },         "ddd": {             "value3": "v3",             "value4": 4         }     } } 

I try a lot of combinations but the only result i get is the following, which is not the expected result:

{   "ccc": {     "value2": "v2",     "value1": "v1"   },   "bbb": {     "value2": "v2",     "value1": "v1"   },   "aaa": {     "value2": "v2",     "value1": "v1"   } } {   "ddd": {     "value4": 4,     "value3": "v3"   },   "bbb": {     "value3": "v3"   },   "aaa": {     "value4": 4,     "value3": "v3"   } } 

Using this command:

jq -s '.[].value' file1 file2 
like image 881
Janfy Avatar asked Oct 22 '13 22:10

Janfy


People also ask

How do I combine multiple JSON objects into one?

We can merge two JSON objects using the putAll() method (inherited from interface java.

How do I combine two JSON arrays?

We can merge two JSON arrays using the addAll() method (inherited from interface java.

Does jq use JSONPath?

JSONPath distinguishes between the "root object or element" ($) and "the current object or element" (.). jq simply uses . to refer to the current JSON entity and so it is context-dependent: it can refer to items in the input stream of the jq process as a whole, or to the output of a filter.


1 Answers

Since 1.4 this is now possible with the * operator. When given two objects, it will merge them recursively. For example,

jq -s '.[0] * .[1]' file1 file2 

Important: Note the -s (--slurp) flag, which puts files in the same array.

Would get you:

{   "value1": 200,   "timestamp": 1382461861,   "value": {     "aaa": {       "value1": "v1",       "value2": "v2",       "value3": "v3",       "value4": 4     },     "bbb": {       "value1": "v1",       "value2": "v2",       "value3": "v3"     },     "ccc": {       "value1": "v1",       "value2": "v2"     },     "ddd": {       "value3": "v3",       "value4": 4     }   },   "status": 200 } 

If you also want to get rid of the other keys (like your expected result), one way to do it is this:

jq -s '.[0] * .[1] | {value: .value}' file1 file2 

Or the presumably somewhat more efficient (because it doesn't merge any other values):

jq -s '.[0].value * .[1].value | {value: .}' file1 file2 
like image 53
Simo Kinnunen Avatar answered Sep 22 '22 14:09

Simo Kinnunen