英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论