首页 > 解决方案 > 用 jq 重构 JSON

问题描述

我有一个这样的 JSON (sample.json):

{
  "sheet1": [
    {
      "hostname": "sv001",
      "role": "web",
      "ip1": "172.17.0.3"
    },
    {
      "hostname": "sv002",
      "role": "web",
      "ip1": "172.17.0.4"
    },
    {
      "hostname": "sv003",
      "role": "db",
      "ip1": "172.17.0.5",
      "ip2": "172.18.0.5"
    }
  ],
  "sheet2": [
    {
      "hostname": "sv004",
      "role": "web",
      "ip1": "172.17.0.6"
    },
    {
      "hostname": "sv005",
      "role": "db",
      "ip1": "172.17.0.7"
    },
    {
      "hostname": "vsv006",
      "role": "db",
      "ip1": "172.17.0.8"
    }
  ],
  "sheet3": []
}

我想提取这样的数据:

表 1

jq '(某事命令)' sample.json

{
    "web": {
        "hosts": [
            "172.17.0.3",
            "172.17.0.4"
        ]
    },
    "db": {
        "hosts": [
            "172.17.0.5"
        ]
    }
}

是否可以使用 jq map 进行重建?(我会将结果重用于 ansible 库存。)

标签: jsonjqobject-construction

解决方案


这是一个简短、直接且高效的解决方案——高效的部分原因是它group_by通过以下通用辅助函数避免了:

def add_by(f;g): reduce .[] as $x ({}; .[$x|f] += [$x|g]);
.sheet1
| add_by(.role; .ip1) 
| map_values( {hosts: .} )

输出

这会产生所需的输出:

{
 "web": {
    "hosts": [
      "172.17.0.3",
      "172.17.0.4"
    ]
  },
  "db": {
    "hosts": [
      "172.17.0.5"
    ]
  }
}

推荐阅读