我想在jq
. 阵列中的每个物件都包含名称栏位,它允许我将两个阵列分组并将其合并为一个。
标签
[
{
"name": "power_branch",
"description": "master"
},
{
"name": "test_branch",
"description": "main"
}
]
跑者
[
{
"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"
}
]
期望输出
[
{
"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 的条目
#!/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
输出
[
{
"name": "power_branch",
"description": "master",
"runner": "power",
"runner_tag": "ubuntu"
},
{
"name": "test_branch",
"description": "main",
"runner": "tester",
"runner_tag": ""
}
]
uj5u.com热心网友回复:
如果您有两个档案labels.json
和runners.json
,则可以--argjson
使用map
由select
.
jq --argjson runners "$(cat runners.json)" '
map(.name as $name | . ($runners[] | select(.name == $name)))
' labels.json
但是,这会将整个 runners 阵列读入您的 shell 命令列空间(--argjson
需要两个字符串:一个名称和一个值),如果 runners 阵列足够大,很容易溢位。
因此,不是使用命令替换 "$(…)"
,您可以直接使用 runners 档案读取--slurpfile
另一个迭代级别的成本[][]
,或者(尽管手册说不要 - 在评论中阅读更多相关信息)--argfile
仅使用单个迭代级别和以前一样:
jq --slurpfile runners runners.json '
map(.name as $name | . ($runners[][] | select(.name == $name)))
' labels.json
jq --argfile runners runners.json '
map(.name as $name | . ($runners[] | select(.name == $name)))
' labels.json
为了规避所有这些问题,@peak建议将input
for 每个档案与-n
选项一起使用。请注意,这要求在顺序读取两个档案时按此确切顺序提供它们。
jq -n 'input as $runners | input |
map(.name as $name | . ($runners[] | select(.name == $name)))
' runners.json labels.json
由于第二个input
(标签)直接作为过滤器的主要输入传递(与运行程序相反,运行程序存盘在变量中供以后使用),这可以通过再次洗掉该-n
选项来进一步简化(档案的顺序仍然很重要) :
jq 'input as $runners |
map(.name as $name | . ($runners[] | select(.name == $name)))
' runners.json labels.json
最后,这是使用SQL 样式运算子的 另一种方法INDEX
,JOIN
该方法已在 jq v1.6 中引入。这也采用了只使用一个的技术input
,而且档案的顺序仍然很重要,因为我们需要 runners 阵列作为过滤器的主要输入。
jq '
JOIN(INDEX(input[]; .name); .name) | map(select(.[1]) | add)
' runners.json labels.json
0 评论