Select a field depending on another field value

Rationale TL;DR

Let’s suppose you want to query a value depending on the value of another field in the json structure.

The solution

jq to the rescue

Let’s suppose we have to deal with a JSON like this:

{
  "zones": [
    {
      "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "name": "gusi.me",
      "ttl": 86400,
      "registrar": "",
      "legacy_dns_host": "",
      "legacy_ns": [
        ...
      ],
      "ns": [
        ...
      ],
      ...
      "records_count": 6
    },
    {
      "id": "yyyyyyyyyyyyyyyyyyyyyyyy",
      "name": "gusi.wtf",
      "ttl": 86400,
      "registrar": "",
      "legacy_dns_host": "",
      "legacy_ns": [],
      "ns": [
        ....
      ],
      ...
      "records_count": 4
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "per_page": 100,
      "previous_page": 1,
      "next_page": 1,
      "last_page": 1,
      "total_entries": 2
    }
  }
}

Let’s suppose we want to query the id value of the zone gusi.me. That would mean that we need to query all the values of the zones array and fetch the id field of the element whose zone is gusi.me. To select that specific we’d use:

echo $json | jq -r '.zones[] | select(.name=="gusi.me")

This will iterate over the zones array, it would then select the element whose name field is gusi.me. That would return this:

{
  "id": "HTiekcmw2cscFZAyNdrnYF",
  "name": "gusi.me",
  ...
  "ns": [
  ...
  ],
  ...
  "records_count": 6
}

Now, we can pipe the resulting json and query for the id field:

echo $json | |  jq -r '.zones[] | select(.name=="gusi.me") | .id'

Note that the | is not a bash pipe but a jq pipe. Internally jq allow us to pipe the resulting json and query it.