如何使用jq合并2个json文件?

我在shell脚本中使用jq工具(jq-json-processor)来parsingjson。

我有2个JSON文件,并希望合并成一个独特的文件

这里的文件内容:

文件1

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

文件2

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

预期结果

 { "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 } } } 

我尝试了很多combinaison,但我得到的唯一结果是以下,这不是预期的结果:

 { "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" } } 

使用这个命令:

 jq -s '.[].value' file1 file2 

从1.4开始,现在可以使用*运算符。 当给定两个对象时,它将recursion地合并它们。 例如,

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

会得到你:

 { "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 } 

如果你也想摆脱其他键(如你的预期结果),一种方法是这样的:

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

或者大概更有效率(因为它不合并任何其他值):

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

使用jq -s add

 $ echo '{"a":"foo","b":"bar"} {"c":"baz","a":0}' | jq -s add { "a": 0, "b": "bar", "c": "baz" } 

这将从标准input读取所有JSON文本到数组( jq -s做到这一点),然后“减less”他们。

add被定义为def add: reduce .[] as $x (null; . + $x); ;,它遍历input数组/对象的值并添加它们。

谁知道你是否仍然需要它,但这里是解决scheme。

一旦你到了--slurp选项,这很容易!

 --slurp/-s: Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once. 

然后, +运营商将做你想做的事情:

 jq -s '.[0] + .[1]' config.json config-user.json 

(注意:如果你想合并内部对象而不是用正确的文件覆盖左边的文件,你需要手动完成)

这是一个recursion(使用* )在任意数量的对象上工作的版本:

 echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' | jq --slurp 'reduce .[] as $item ({}; . * $item)' { "A": { "a": 1, "b": 2 }, "B": 3 } 

首先,{“value”:.value}可以缩写为{value}。

其次,–argfile选项(可用于jq 1.4和jq 1.5)可能是有趣的,因为它避免了必须使用–slurp选项。

把它们放在一起,两个文件中的两个对象可以按如下方式组合:

 $ jq --argfile o1 file1 --argfile o2 file2 '$o1 * $o2 | {value}'