json - 如何使用公用 key 组合并附加两个json文件而不丢失其他数据

标签 json shell jq

我有两个 json 文件,其中有几个 json 对象。 我想通过使用 jq 和 group_by(.id) 在 Linux 上合并两个 json 文件 其实我不需要使用jq,但我需要制作linux shell脚本文件。

当然,我尝试了很多解决方案,但它们并没有完全按照我想要的方式工作。

输入1:file1.json

{"id":"1234", "branch": "master", "arr":["say", "one", "more"]}
{"id":"102", "branch": "master", "arr":["yes"]}
{"id":"1228", "branch": "master"}

输入2:file2.json

{"id":"1234", "branch": "dev", "other": "value", "arr":["what"]}
{"id":"102", "branch": "dev"}
{"id":"0806", "branch": "master"}

我期望的是

{"id":"1234", "branch": ["master", "dev"], "other": "value", "arr":["say", "one", "more", "what"]}
{"id":"102", "branch": ["master", "dev"], "arr":["yes"]}
{"id":"1228", "branch": "master"}
{"id":"0806", "branch": "master"}

但实际输出是这样的

{"id":"1234", "branch": "dev", "other": "value", "arr":["what"]}
{"id":"102", "branch": "dev"}
{"id":"0806", "branch": "master"}

最佳答案

下面,我们使用通用函数combine来组合两个对象,如下定义。

使用此函数,并使用如下调用:

jq -n -f combine.jq --slurpfile f1 file1.json --slurpfile f2 file2.json

假设你的jq有INDEX/2,那么只需编写以下即可获得解决方案:

INDEX( $f1[]; .id) as $d1
| INDEX( $f2[]; .id) as $d2
| reduce (($d1+$d2)|keys_unsorted)[] as $id
    ({}; .[$id] = ($d1[$id] | combine($d2[$id])) )
| .[]

也就是说,我们为两个文件分别构造一个字典,然后将相应键处的对象组合起来,然后生成所需的流。

如果您安装的 jq 没有 INDEX/2,那么现在是升级的好时机,但另一种选择是从builtin.jq 复制其 def (请参阅“注释“以下)。

合并/1

在下面的内容中,针对 jq 1.5 或更高版本,组合值的详细信息留给内部函数 aggregate

# Combine . with obj using aggregate/2 for shared keys whose values differ
def combine($obj):

  # Combine two entities in an array-oriented fashion:
  # if both are arrays:  a + b 
  # else if a is an array: a + [b]
  # else if b is an array: [a] + b
  # else [a, b]
  def aggregate(a; b):
    if (a|type) == "array" then
      if (b|type) == "array" then a + b
      else a + [b]
      end
    else
      if (b|type) == "array" then [a] + b
      else [a, b]
      end
    end;

  if . == null then $obj
  elif $obj == null then .
  else reduce ($obj|keys_unsorted[]) as $key (.;
         if .[$key] == $obj[$key] then . 
         else .[$key] = if has($key) and ($obj|has($key))
                        then aggregate( .[$key]; $obj[$key] )
                        else .[$key] + $obj[$key]
                end
         end )
   end ;

关于json - 如何使用公用 key 组合并附加两个json文件而不丢失其他数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55806642/

相关文章:

java - 如何在 Retrofit for Android 中处理可选的 JSON 字段?

javascript - JSON获取并在html页面上显示

python - 有没有办法防止 pandas to_json 添加\?

linux shell脚本printf数字格式颜色

json - 解析 JSON 和其他字段中的 JSON 字符串

json - 使用groovy读取json的名称

python - 如何将 python "login shell"与 "call"一起使用?

linux - shell脚本中的su命令

indexing - 如何使用 jq 将数组中对象的数组索引注入(inject)到对象中

json - 迭代项目 json 数组