skip to Main Content

I have a complex (at least for me) issue with jq, and this structure :

{
  "os": {
    "ubuntu": {
      "16.04": {
        "codename": "xenial",
        "bootstrap": "preseed",
        "guest_type": "ubuntu64Guest",
        "iso_name": "ubuntu-16.04.7-server-amd64.iso",
        "iso_checksum": "9bb30a2ea6466b0c02aacfa96f6e3516",
      },
      "18.04": {
        "codename": "bionic",
        "bootstrap": "preseed",
        "guest_type": "ubuntu64Guest",
        "iso_name": "ubuntu-18.04.2-server-amd64.iso",
        "iso_checksum": "34416ff83179728d54583bf3f18d42d2",
        "arm": {
          "iso_name": "ubuntu-18.04.5-server-arm64.iso",
          "iso_checksum": "5056eaf87425b550376e6733b05de6e9"
        }
      }
    },
    "rhel": {
      "7.4": {
        "codename": "maipo",
        "bootstrap": "kickstart",
        "guest_type": "rhel7_64Guest",
        "iso_name": "rhel-server-7.4-x86_64-boot.iso",
        "iso_checksum": "94ad0929b79b5d13b33acafc8da8d364",
      },
      "7.6": {
        "codename": "maipo",
        "bootstrap": "kickstart",
        "guest_type": "rhel7_64Guest",
        "iso_name": "rhel-server-7.6-x86_64-boot.iso",
        "iso_checksum": "4a611d2bbfa6912eada91096af14ec84",
      }
    }
  }
}

I need to get the "ubuntu" node content by searching it with "18.04", without knowing the "ubuntu" node key name.
So if i search the children node named "7.4", it should identify its parent as "rhel" and returns it.

Basically, with an os version, i should get the os name, but i have no way of knowing the os name beforehand.

I tried a few commands (didn’t keep them sorry), with the help of this cheatsheet, without luck :
https://gist.github.com/olih/f7437fb6962fb3ee9fe95bda8d2c8fa4

It is even possible ?

Thanks.

2

Answers


  1. I need to get the "ubuntu" node content

    You can use .[] to get all nodes’ contents, and has to check for their keys:

    jq '.os[] | select(has("18.04"))'
    
    {
      "16.04": {
        "codename": "xenial",
        "bootstrap": "preseed",
        "guest_type": "ubuntu64Guest",
        "iso_name": "ubuntu-16.04.7-server-amd64.iso",
        "iso_checksum": "9bb30a2ea6466b0c02aacfa96f6e3516"
      },
      "18.04": {
        "codename": "bionic",
        "bootstrap": "preseed",
        "guest_type": "ubuntu64Guest",
        "iso_name": "ubuntu-18.04.2-server-amd64.iso",
        "iso_checksum": "34416ff83179728d54583bf3f18d42d2",
        "arm": {
          "iso_name": "ubuntu-18.04.5-server-arm64.iso",
          "iso_checksum": "5056eaf87425b550376e6733b05de6e9"
        }
      }
    }
    

    Demo

    If you want the object with the "ubuntu" field included, update |= the nodes:

    jq '.os | .[] |= select(has("18.04"))'
    
    {
      "ubuntu": {
        "16.04": {
          "codename": "xenial",
          "bootstrap": "preseed",
          "guest_type": "ubuntu64Guest",
          "iso_name": "ubuntu-16.04.7-server-amd64.iso",
          "iso_checksum": "9bb30a2ea6466b0c02aacfa96f6e3516"
        },
        "18.04": {
          "codename": "bionic",
          "bootstrap": "preseed",
          "guest_type": "ubuntu64Guest",
          "iso_name": "ubuntu-18.04.2-server-amd64.iso",
          "iso_checksum": "34416ff83179728d54583bf3f18d42d2",
          "arm": {
            "iso_name": "ubuntu-18.04.5-server-arm64.iso",
            "iso_checksum": "5056eaf87425b550376e6733b05de6e9"
          }
        }
      }
    }
    

    Demo

    Login or Signup to reply.
  2. Basically, with an os version, i should get the os name, but i have no way of knowing the os name beforehand.

    You can use to_entires() with select() and has() to filter those which nested object contains the desired key: select(.value | has("18.04")).

    Then return the parent’s key to get the OS name (.key):

    .os | to_entries[] | select(.value | has("18.04")).key
    // "ubuntu"
    
    .os | to_entries[] | select(.value | has("7.6")).key
    // "rhel"
    

    JqPlay Demo

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