jq group by和Increment同时

时间:2018-04-04 09:45:37

标签: arrays json grouping jq

  

示例 input1.json


[{
    "organizationId": "org1",
    "status": "UP",
    "server": "server1",
    "somekey1" : "somevalue1"
}, 
{
    "organizationId": "org1",
    "status": "DOWN",
    "server": "server2",
    "somekey2" : "somevalue2"
},
{
    "organizationId": "org1",
    "status": "DOWN",
    "server": "server3"
},
{
    "organizationId": "org2",
    "server": "server1",
    "status": "UP",
    "somekey2" : "somevalue2"
},
{
    "organizationId": "org2",
    "server": "server2",
    "status": "UP",
    "somekey4" : "somevalue4"
}]

  

预期 output.json


[{
        "organizationId": "org1",
        "server1": "UP",
        "server2": "DOWN",
        "server3": "DOWN",
        "Down_Count": 2,
        "somekey2" : "somevalue2"
    },
    {
        "organizationId": "org2",
        "server1": "UP",
        "server2": "UP",
        "Down_Count": 0,
       "somekey2" : "somevalue2"
    }]

输入是两个文件的数组对象。我的目标是

  1. 通过Down_Count分组来增加和填充新字段organizationId。我可以有多个具有相同organizationId的记录。因此,计数应该增加该状态DOWN的次数。
  2. 合并serverstatus字段。例如,"server":"server1", "status":"down"应该直接在最终输出中作为server1:down。我可以使用jq '.[] |= . + {(.server):.status}'
  3. 独立尝试这个
  4. 所有对象中都没有所有键。因此,我应该能够将我想要的键添加到最终输出中。让我们假设我知道要添加的密钥名称。在最终输出中,我只添加了"somekey2" : "somevalue2"
  5. 我发现使用jq cmd行处理器一起实现所有这些困难有些困难。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

jq 解决方案:

jq 'group_by(.organizationId) 
    | map(reduce .[] as $o ({"Down_Count" : 0};
              if $o["status"] == "DOWN" then .Down_Count += 1 else . end
              | . + { ($o["server"]) : $o["status"],
                          "organizationId" : $o["organizationId"] }
          ))' input.json

输出:

[
  {
    "Down_Count": 2,
    "server1": "UP",
    "organizationId": "org1",
    "server2": "DOWN",
    "server3": "DOWN"
  },
  {
    "Down_Count": 0,
    "server1": "UP",
    "organizationId": "org2",
    "server2": "UP"
  }
]

答案 1 :(得分:1)

这是您可以采取的另一种方法:

group_by(.organizationId) | map(
    reduce ([., [range(length)]] | transpose[]) as [$o,$i] (
        {
            organizationId: .[0].organizationId,
            Down_Count: (map(select(.status=="DOWN")) | length)
        };
        reduce $keys[] as $k (
            .["server\($i+1)"] = $o.status;
            if $o | has($k) then .[$k] = $o[$k] else . end
        )
    )
)

只需传入要复制的名为$keys的键数组。如果它存在于其中一个对象中,它将被复制到结果对象。

$ cat input.json
[{
    "organizationId": "org1",
    "status": "UP",
    "server": "server1",
    "somekey1" : "somevalue1"
}, 
{
    "organizationId": "org1",
    "status": "DOWN",
    "server": "server2",
    "somekey2" : "somevalue2"
},
{
    "organizationId": "org1",
    "status": "DOWN",
    "server": "server3"
},
{
    "organizationId": "org2",
    "server": "server1",
    "status": "UP",
    "somekey2" : "somevalue2"
},
{
    "organizationId": "org2",
    "server": "server2",
    "status": "UP",
    "somekey4" : "somevalue4"
}]
$ cat program.jq
group_by(.organizationId) | map(
    reduce ([., [range(length)]] | transpose[]) as [$o,$i] (
        {
            organizationId: .[0].organizationId,
            Down_Count: (map(select(.status=="DOWN")) | length)
        };
        reduce $keys[] as $k (
            .["server\($i+1)"] = $o.status;
            if $o | has($k) then .[$k] = $o[$k] else . end
        )
    )
)
$ jq --argjson keys '["somekey2"]' -f program.jq input.json
[
  {
    "organizationId": "org1",
    "Down_Count": 2,
    "server1": "UP",
    "server2": "DOWN",
    "somekey2": "somevalue2",
    "server3": "DOWN"
  },
  {
    "organizationId": "org2",
    "Down_Count": 0,
    "server1": "UP",
    "somekey2": "somevalue2",
    "server2": "UP"
  }
]