合并JSON文件通过Bash或JQ

huangapple go评论59阅读模式
英文:

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

Demo

答案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 &#39;
reduce inputs as {$test, $id} ({};
  .[$id] += $test
)
| keys_unsorted[] as $id
| {test: .[$id], $id}&#39; files...

<sup>Online demo</sup>

huangapple
  • 本文由 发表于 2023年5月28日 18:11:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350965.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定