如何使用 jq 合并 2 个文件中的 2 个 JSON 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19529688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to merge 2 JSON objects from 2 files using jq?
提问by Janfy
I'm using the jqtools (jq-json-processor) in shell script to parse json.
我在 shell 脚本中使用jq工具(jq-json-processor)来解析 json。
I've got 2 json files and want to merge them into one unique file
我有 2 个 json 文件,想将它们合并成一个独特的文件
Here the content of files:
这里是文件的内容:
file1
文件 1
{
"value1": 200,
"timestamp": 1382461861,
"value": {
"aaa": {
"value1": "v1",
"value2": "v2"
},
"bbb": {
"value1": "v1",
"value2": "v2"
},
"ccc": {
"value1": "v1",
"value2": "v2"
}
}
}
file2
文件 2
{
"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 combinaison 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
回答by Simo Kinnunen
Since 1.4 this is now possible with the *operator. When given two objects, it will merge them recursively. For example,
从 1.4 开始,*操作员现在可以做到这一点。当给定两个对象时,它将递归合并它们。例如,
jq -s '.[0] * .[1]' file1 file2
Important: Note the -s (--slurp)flag, which puts files in the same array.
重要提示:请注意-s (--slurp)将文件放在同一个数组中的标志。
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
回答by user2259432
Use jq -s add:
使用jq -s add:
$ echo '{"a":"foo","b":"bar"} {"c":"baz","a":0}' | jq -s add
{
"a": 0,
"b": "bar",
"c": "baz"
}
This reads all JSON texts from stdin into an array (jq -sdoes that) then it "reduces" them.
这jq -s会将所有 JSON 文本从 stdin 读取到一个数组中(这样做)然后“减少”它们。
(addis defined as def add: reduce .[] as $x (null; . + $x);, which iterates over the input array's/object's values and adds them. Object addition == merge.)
(add定义为def add: reduce .[] as $x (null; . + $x);,它遍历输入数组/对象的值并添加它们。对象添加 == 合并。)
回答by FiloSottile
Who knows if you still need it, but here is the solution.
谁知道您是否仍然需要它,但这是解决方案。
Once you get to the --slurpoption, it's easy!
一旦找到--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.
Then the +operator will do what you want:
然后+操作员将执行您想要的操作:
jq -s '.[0] + .[1]' config.json config-user.json
(Note: if you want to merge inner objects instead of just overwriting the left file ones with the right file ones, you will need to do it manually)
(注意:如果你想合并内部对象而不是用右边的文件覆盖左边的文件,你需要手动完成)
回答by jrib
Here's a version that works recursively (using *) on an arbitrary number of objects:
这是一个*在任意数量的对象上递归(使用)的版本:
echo '{"A": {"a": 1}}' '{"A": {"b": 2}}' '{"B": 3}' | jq --slurp 'reduce .[] as $item ({}; . * $item)'
{
"A": {
"a": 1,
"b": 2
},
"B": 3
}
回答by peak
First, {"value": .value} can be abbreviated to just {value}.
首先,{"value": .value} 可以缩写为 {value}。
Second, the --argfile option (available in jq 1.4 and jq 1.5) may be of interest as it avoids having to use the --slurp option.
其次, --argfile 选项(在 jq 1.4 和 jq 1.5 中可用)可能很有趣,因为它避免了必须使用 --slurp 选项。
Putting these together, the two objects in the two files can be combined in the specified way as follows:
将这些放在一起,两个文件中的两个对象可以按照指定的方式组合如下:
$ jq -n --argfile o1 file1 --argfile o2 file2 '$o1 * $o2 | {value}'
The '-n' flag tells jq not to read from stdin, since inputs are coming from the --argfile options here.
'-n' 标志告诉 jq 不要从 stdin 读取,因为这里的输入来自 --argfile 选项。
回答by dngray
This can be used to merge any number of files specified on the command:
这可用于合并命令中指定的任意数量的文件:
jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json
jq -rs 'reduce .[] as $item ({}; . * $item)' file1.json file2.json file3.json ... file10.json
or this for any number of files
或者这适用于任意数量的文件
jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json
jq -rs 'reduce .[] as $item ({}; . * $item)' ./*.json

