Home > other >  jq: convert comma seperated values into JSON
jq: convert comma seperated values into JSON

Time:04-21

I have a comma separated string of IP addresses (one or more)

nodes=192.168.56.111,192.168.56.112,192.168.56.113

Using jq, I would like to create a JSON document that looks like this:

{
  "clusters": [
    {
      "nodes": [
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.56.111"
              ],
              "storage": [
                "192.168.56.111"
              ]
            },
            "zone": 1
          },
          "devices": [
            {
              "name": "/dev/sdb",
              "destroydata": false
            }
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.56.112"
              ],
              "storage": [
                "192.168.56.112"
              ]
            },
            "zone": 1
          },
          "devices": [
            {
              "name": "/dev/sdb",
              "destroydata": false
            }
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.56.113"
              ],
              "storage": [
                "192.168.56.113"
              ]
            },
            "zone": 1
          },
          "devices": [
            {
              "name": "/dev/sdb",
              "destroydata": false
            }
          ]
        }
      ]
    }
  ]
}

What I have so far:

nodes=192.168.56.111,192.168.56.112,192.168.56.113

jq --arg ip "$nodes" '.clusters[].nodes[].node.hostnames.manage |= ($ip | split(","))' <<<'{"clusters":[{"nodes":[{"node":{"hostnames":{"manage":[],"storage":[]},"zone":1},"devices":[{"name":"/dev/sdb","destroydata":false}]}]}]}'

this has 2 problems:

  1. .clusters[].nodes[].node is not replicated.
  2. .clusters[].nodes[].node.hostnames.storage is missing.

CodePudding user response:

You could use the splitting result with map to create the array under .clusters[0].nodes:

nodes=192.168.56.111,192.168.56.112,192.168.56.113

jq -R '
  {clusters: [{nodes: (./"," | map({
    node: {hostnames: {manage: [.], storage: [.]}, zone: 1},
    devices: [{name: "/dev/sdb", destroydata: false}]
  }))}]}
' <<< "$nodes"
{
  "clusters": [
    {
      "nodes": [
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.56.111"
              ],
              "storage": [
                "192.168.56.111"
              ]
            },
            "zone": 1
          },
          "devices": [
            {
              "name": "/dev/sdb",
              "destroydata": false
            }
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.56.112"
              ],
              "storage": [
                "192.168.56.112"
              ]
            },
            "zone": 1
          },
          "devices": [
            {
              "name": "/dev/sdb",
              "destroydata": false
            }
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "192.168.56.113"
              ],
              "storage": [
                "192.168.56.113"
              ]
            },
            "zone": 1
          },
          "devices": [
            {
              "name": "/dev/sdb",
              "destroydata": false
            }
          ]
        }
      ]
    }
  ]
}

Demo

  • Related