jq 在公共密钥上加入

ewo*_*woj 5 merge json join jq

我很陌生jq,这篇文章是不了解背后机制的结果jq。我可以开发一个 bash 脚本,它可以做我想要的事情,但是 jq 和它的JSON超能力引起了我的兴趣,我想通过应用于现实世界的场景来学习它。这是一个...

顺便说一句,我尝试利用现有的 jq 相关 SO 解决方案来合并/加入 JSON,但失败了。

我最接近我需要的是使用 INDEX 和 $x + 的串联。,但是我只从第二个 (c2) 中获取最后一项json

所以,我的问题如下:

有两个JSON文件:

  • JSON#1 将具有唯一的“id”和“type”键 - 在其他键/值对中,我已将其删除以便更好地阐明我的帖子。

  • JSON#2 将包含多个/非唯一的“type”键,我想在其上匹配这两个 JSON 文件。# JSON2 还将包含其他键/值对,这些键/值对预计将包含在结果输出中。

我的输出要求是:我想获得 c1 和 c2 数组之间匹配键/值对的所有组合的(每行一个或单个数组)列表,其中“type”键(字符串)的值在之间匹配c1 和 c2 完全一样。

JSON还有一个问题,扩展解决方案以同时在三个文件之间执行类似的匹配/连接(再次在特定键的相同值上)会困难多少?

任何有关如何解决和理解如何解决此问题的帮助,甚至只是提示,将不胜感激!

第一个输入文件:JSON#1,数组 c1(集合 1)

{ "c1":
[
{ "c1id":1, "type":"alpha" },
{ "c1id":2, "type":"beta" }
]
}
Run Code Online (Sandbox Code Playgroud)

第二个输入文件:JSON#2,数组 c2(集合 2)

{
"c2":
[
{ "c2id":1,"type":"alpha","serial":"DDBB001"} ,
{ "c2id":2,"type":"beta","serial":"DDBB007"} ,
{ "c2id":3,"type":"alpha","serial":"DDTT005"} ,
{ "c2id":4,"type":"beta","serial":"DDAA002"} ,
{ "c2id":5,"type":"yotta","serial":"DDCC017"}
]
}
Run Code Online (Sandbox Code Playgroud)

预期输出:

{"c1id":1,"type":"alpha","c2id":1,"serial":"DDBB001"}
{"c1id":1,"type":"alpha","c2id":3,"serial":"DDTT005"}
{"c1id":2,"type":"beta","c2id":2,"serial":"DDBB007"}
{"c1id":2,"type":"beta","c2id":4,"serial":"DDAA002"} 
Run Code Online (Sandbox Code Playgroud)

您会注意到 c2 中的类型“yotta”未包含在输出中。这是预料之中的。只有 c1 中存在且匹配 c2 的“类型”才会出现在结果中。我想这是一个匹配/连接练习所暗示的——我添加它只是为了清楚起见——我希望它有效。

Wee*_*ble 2

下面是使用 INDEX 和 JOIN 的示例:

jq --compact-output --slurpfile c1 c1.json '
    INDEX(
        $c1[0].c1[];
        .type
    ) as $index |
    JOIN(
        $index;
        .c2[];
        .type;
        reverse|add
    )
' c2.json
Run Code Online (Sandbox Code Playgroud)

INDEX 的第一个参数需要生成一个项目流,这就是我们申请[]单独从数组中获取项目的原因。第二个参数选择我们的索引键。

我们使用 JOIN 的四个参数版本。第一个参数是索引本身,第二个参数是要连接到索引的对象流,第三个参数从流对象中选择查找键,第四个参数是用于组装连接对象的表达式。该表达式的输入是一个包含两项的数组的流,每个数组看起来像这样:

[{"c2id":1,"type":"alpha","serial":"DDBB001"},{"c1id":1,"type":"alpha"}]
Run Code Online (Sandbox Code Playgroud)

因为我们只想组合我们刚刚使用的对象中的所有键和值add,但我们首先reverse使用数组将 c1 字段很好地排列在 c2 字段之前。最终的结果如你所愿:

{"c1id":1,"type":"alpha","c2id":1,"serial":"DDBB001"}
{"c1id":2,"type":"beta","c2id":2,"serial":"DDBB007"}
{"c1id":1,"type":"alpha","c2id":3,"serial":"DDTT005"}
{"c1id":2,"type":"beta","c2id":4,"serial":"DDAA002"}
Run Code Online (Sandbox Code Playgroud)