skip to Main Content

I have the following json:

{
  "virtual_machines": [
    {
      "guest_name": "guest1",
      "mac_address": [
        "00:01:02:03:04:05"
      ],
      "vm_network": {
        "00:01:02:03:04:05": {
          "ipv4": [
            "192.168.2.23"
          ],
          "ipv6": [
            "fe80::896:2e12:c059:4237"
          ]
        },
        "c2:e3:7c:ac:60:c5": {
          "ipv4": [
            "10.42.0.0"
          ],
          "ipv6": []
        },
        "5a:00:fb:5e:3d:65": {
          "ipv4": [
            "10.42.0.1"
          ],
          "ipv6": []
        }
      }
    },
    {
      "guest_name": "guest2",
      "ip_address": "172.20.8.34",
      "mac_address": [
        "10:11:12:13:14:15",
        "30:31:32:33:34:35"
      ],
      "vm_network": {
        "10:11:12:13:14:15": {
          "ipv4": [
            "172.20.8.34"
          ],
          "ipv6": []
        },
        "30:31:32:33:34:35": {
          "ipv4": [
            "172.16.172.34",
            "172.16.172.30"
          ],
          "ipv6": [
            "fe80::ad7f:c2:f621:e718"
          ]
        }
      }
    }
  ]
}

From that JSON, I need to get all ipv4 from vm_network[] that have an entry at mac_address[] and I need to print that as
$guest_name, $mac_address, $ipv4

The best I could get was the guest_name followed by the ipv4, but i can’t find a way to get the mac_address for that ipv4:

jq -r  '.virtual_machines[] | .guest_name  + ","+ (.vm_network[.mac_address[]] |.ipv4[])' < json_file
guest1,192.168.2.23
guest2,172.20.8.34
guest2,172.16.172.34
guest2,172.16.172.30

The output i need is:

guest1,00:01:02:03:04:05,192.168.2.23
guest2,10:11:12:13:14:15,172.20.8.34
guest2,30:31:32:33:34:35,172.16.172.34
guest2,30:31:32:33:34:35,172.16.172.30

Can anyone help me to acomplish that?
Please not that there can be more MAC keys in vm_network[] than in mac_address[], but I am only interested in those that have a matching entry in mac_address[].

2

Answers


  1. Bind values to variables, so you can re-use them later:

    .virtual_machines[] | .guest_name as $g | .mac_address[] as $m
    | .vm_network[$m].ipv4[] | [$g, $m, .] | join(",")
    
    guest1,00:01:02:03:04:05,192.168.2.23
    guest2,10:11:12:13:14:15,172.20.8.34
    guest2,30:31:32:33:34:35,172.16.172.34
    guest2,30:31:32:33:34:35,172.16.172.30
    

    Demo

    Login or Signup to reply.
  2. A solution that does not use variables:

    .virtual_machines
    | map(
      { guest_name, mac_address: .mac_address[], ipv4: .vm_network | map_values(.ipv4) }
      | { guest_name, mac_address, ipv4: (.ipv4[.mac_address] // [])[] }
    )
    | .[]
    | join(",")
    

    Check it online.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search