发布
社区首页 >问答首页 >用重复键合并json数组

用重复键合并json数组
EN

Stack Overflow用户
提问于 2022-01-03 14:35:00
回答 1查看 291关注 0票数 6

我想在jq的帮助下合并两个json数组。数组中的每个对象都包含name字段,允许我按其分组并将两个数组合并为一个。

标签

代码语言:javascript
代码运行次数:0
复制
[
  {
    "name": "power_branch",
    "description": "master"
  },
  {
    "name": "test_branch",
    "description": "main"
  }
]

跑步者

代码语言:javascript
代码运行次数:0
复制
[
  {
    "name": "power_branch",
    "runner": "power",
    "runner_tag": "macos"
  },
  {
    "name": "power_branch",
    "runner": "power",
    "runner_tag": "ubuntu"
  },
  {
    "name": "test_branch",
    "runner": "tester",
    "runner_tag": ""
  },
  {
    "name": "development",
    "runner": "dev",
    "runner_tag": "ubuntu"
  }
]

期望输出

代码语言:javascript
代码运行次数:0
复制
[
  {
    "name": "power_branch",
    "description": "master",
    "runner": "power",
    "runner_tag": "macos"
  },
  {
    "name": "power_branch",
    "description": "master",
    "runner": "power",
    "runner_tag": "ubuntu"
  },
  {
    "name": "test_branch",
    "description": "main",
    "runner": "tester",
    "runner_tag": ""
  }
]

我尝试使用以下脚本,但是power_branch条目被覆盖,相反,我想要另一个具有不同runner_tag的条目

代码语言:javascript
代码运行次数:0
复制
#!/usr/bin/bash

LABELS='[{"name": "power_branch","description": "master"},{"name": "test_branch","description": "main"}]'
RUNNERS='''
[
  { "name": "power_branch", "runner": "power", "runner_tag": "macos" },
  { "name": "power_branch", "runner": "power", "runner_tag": "ubuntu" },
  { "name": "test_branch", "runner": "tester", "runner_tag": "" },
  { "name": "development", "runner": "dev", "runner_tag": "ubuntu" }
]
'''

FINAL=$(jq -s '[ .[0] + .[1] | group_by(.name)[] | select(length > 1) | add]' <(echo $LABELS) <(echo $RUNNERS))
echo $FINAL

输出

代码语言:javascript
代码运行次数:0
复制
[
  {
    "name": "power_branch",
    "description": "master",
    "runner": "power",
    "runner_tag": "ubuntu"
  },
  {
    "name": "test_branch",
    "description": "main",
    "runner": "tester",
    "runner_tag": ""
  }
]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-03 14:47:23

如果您有两个文件labels.jsonrunners.json,则可以使用--argjson将后者(运行程序)读入变量中,并使用map将由select确定的相应字段附加到输入数组(标签)的每个元素中。

代码语言:javascript
代码运行次数:0
复制
jq --argjson runners "$(cat runners.json)" '
  map(.name as $name | . + ($runners[] | select(.name == $name)))
' labels.json

但是,这会将整个运行程序数组读入shell命令行空间(--argjson使用两个字符串:一个名称和一个值),如果运行程序数组足够大,该字符串很容易溢出。

因此,与使用命令替换 "$(…)"不同,您可以直接使用--slurpfile读取运行程序文件,以支付另一个迭代级别[][]的成本,或者(尽管手册在注释中说不要更多地阅读),也可以像以前一样使用只有一个迭代级别的--argfile

代码语言:javascript
代码运行次数:0
复制
jq --slurpfile runners runners.json '
  map(.name as $name | . + ($runners[][] | select(.name == $name)))
' labels.json
代码语言:javascript
代码运行次数:0
复制
jq --argfile runners runners.json '
  map(.name as $name | . + ($runners[] | select(.name == $name)))
' labels.json

为了避免所有这些问题,请将每个文件的建议-n选项一起使用input @P峰值-n。请注意,这要求在按顺序读取两个文件时,按此顺序提供它们。

代码语言:javascript
代码运行次数:0
复制
jq -n 'input as $runners | input |
  map(.name as $name | . + ($runners[] | select(.name == $name)))
' runners.json labels.json

由于第二个input (标签)作为过滤器的主要输入直接传递(相对于存储在变量中供以后使用的运行程序),可以通过再次删除-n选项(文件的顺序仍然重要)来进一步简化:

代码语言:javascript
代码运行次数:0
复制
jq 'input as $runners |
  map(.name as $name | . + ($runners[] | select(.name == $name)))
' runners.json labels.json

最后,这里还有另一种使用SQL风格运算符 INDEXJOIN的方法,它们是在JQv1.6中引入的。这还使用了仅使用一个input的技术,而且文件的顺序仍然很重要,因为我们需要运行程序数组作为过滤器的主要输入。

代码语言:javascript
代码运行次数:0
复制
jq '
  JOIN(INDEX(input[]; .name); .name) | map(select(.[1]) | add)
' runners.json labels.json
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70567330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档