Search code examples
curljqdhcp

jq: select output based on one of the field


I use curl and jq to query and parse output from the Kea DHCP server, output comes as this:

% curl -s -X POST -H "Content-Type: application/json" -d '{ "command": "lease4-get-all", "service": [ "dhcp4" ] }' http://localhost:8000 | jq '.'
    [
      {
        "arguments": {
          "leases": [
            {
              "cltt": 1658763299,
              "fqdn-fwd": false,
              "fqdn-rev": false,
              "hostname": "",
              "hw-address": "2c:ea:7f:ff:f6:36",
              "ip-address": "192.168.1.2",
              "state": 0,
              "subnet-id": 1,
              "valid-lft": 3600
            },
            {
              "cltt": 1658763207,
              "fqdn-fwd": false,
              "fqdn-rev": false,
              "hostname": "",
              "hw-address": "2c:ea:7f:ff:f6:9c",
              "ip-address": "192.168.1.3",
              "state": 0,
              "subnet-id": 1,
              "valid-lft": 3600
            }
          ]
        },
        "result": 0,
        "text": "2 IPv4 lease(s) found."
      }
    ]

Since I'm only interested in two fields, hw-address and ip-address, I modified jq command to filter output:

% curl -s -X POST -H "Content-Type: application/json" -d '{ "command": "lease4-get-all", "service": [ "dhcp4" ] }' http://localhost:8000 | jq --raw-output '.[0].arguments.leases[] | "\(.["hw-address"]) \(.["ip-address"])"'

However when result is not 0, the output is different:

[
  {
    "result": 1,
    "text": "unable to forward command to the dhcp4 service: No such file or directory. The server is likely to be offline"
  }
]

and my above command won't work. Is there a way to produce output I need, but only for result == 0 (success) ? I tried to use select:

jq --raw-output '.[0].arguments | select(.result != 0)'

and it works in both cases, result == 0 and otherwise (error), but I can't find the way to dump only hw-address and ip-address fields. What am I missing?


Solution

  • First, select only those with .result == 0, then navigate down to .arguments.leases[], and eventually output your information:

    jq --raw-output '
      .[0] | select(.result == 0) | .arguments.leases[]
      | "\(.["hw-address"]) \(.["ip-address"])"
    '
    
    2c:ea:7f:ff:f6:36 192.168.1.2
    2c:ea:7f:ff:f6:9c 192.168.1.3
    

    Demo