英文:
Merge JSON Files via Bash or JQ
问题
我有包含压缩JSON的文件。所有JSON都具有相同的根片段 "id" 和 "test":
file1.json:
{"test":{"a":2},"id":"850303847"}
{"test":{"a":3},"id":"2742540872"}
{"test":{"a":4},"id":"1358887220"}
file2.json:
{"test":{"b":3},"id":"850303847"}
{"test":{"b":3},"id":"2742540872"}
{"test":{"b":4},"id":"1358887220"}
file3.json
{"test":{"c":8},"id":"850303847"}
{"test":{"c":4},"id":"2742540872"}
{"test":{"c":5},"id":"1358887220"}
我想要根据它们的ID合并这些文件,结果如下:
{"test":{"a":2,"b":3,"c":8},"id":"850303847"}
{"test":{"a":3,"b":3,"c":4},"id":"2742540872"}
{"test":{"a":4,"b":4,"c":5},"id":"1358887220"}
我查看了 jq -s 选项,但未找到方法。有没有办法在Bash中实现这一目标(使用或不使用JQ)?
英文:
I've go files containing compressed JSONs. All JSONs having the same root fragments "id" and "test":
file1.json:
{"test":{"a":2},"id":"850303847"}
{"test":{"a":3},"id":"2742540872"}
{"test":{"a":4},"id":"1358887220"}
file2.json:
{"test":{"b":3},"id":"850303847"}
{"test":{"b":3},"id":"2742540872"}
{"test":{"b":4},"id":"1358887220"}
file3.json
{"test":{"c":8},"id":"850303847"}
{"test":{"c":4},"id":"2742540872"}
{"test":{"c":5},"id":"1358887220"}
I would like to merge these Files based on it's IDs resulting to:
{"test":{"a":2,"b":3,"c":8},"id":"850303847"}
{"test":{"a":3,"b":3,"c":4},"id":"2742540872"}
{"test":{"a":4,"b":4,"c":5},"id":"1358887220"}
I've looked into jq -s option for this but fail to find a way. Any ideas how to achieve in Bash (with or without JQ)?
答案1
得分: 3
你可以使用reduce将所有的inputs合并成一个对象,以.id作为键,使用*进行深度合并,然后遍历字段.[]以再次获得流(使用-c标志以获得紧凑的输出):
jq -nc 'reduce inputs as $i ({}; .[$i.id] |= (. // {}) * $i) | .[]' file*.json
{"test":{"a":2,"b":3,"c":8},"id":"850303847"}
{"test":{"a":3,"b":3,"c":4},"id":"2742540872"}
{"test":{"a":4,"b":4,"c":5},"id":"1358887220"}
英文:
You could reduce all inputs into an object with .id as key, deep-merge using *, then iterate over the fields .[] to obtain a stream again (use the -c flag for compact output):
jq -nc 'reduce inputs as $i ({}; .[$i.id] |= (. // {}) * $i) | .[]' file*.json
{"test":{"a":2,"b":3,"c":8},"id":"850303847"}
{"test":{"a":3,"b":3,"c":4},"id":"2742540872"}
{"test":{"a":4,"b":4,"c":5},"id":"1358887220"}
答案2
得分: 1
这是一种方式:
jq -nc '
reduce inputs as {$test, $id} ({};
.[$id] += $test
)
| keys_unsorted[] as $id
| {test: .[$id], $id}' files...
<sup>在线演示</sup>
英文:
Here is one way:
jq -nc '
reduce inputs as {$test, $id} ({};
.[$id] += $test
)
| keys_unsorted[] as $id
| {test: .[$id], $id}' files...
<sup>Online demo</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论