mzpq
mzpq

Reputation: 404

Selecting objects from a list with jq based on a value, accessing the top-level object

So I have a structure like this:

[
{
  "name": "aaaaa",
  "type": "A",
  "class": "IN",
  "status": "NOERROR",
  "data": {
    "answers": [
      {
        "ttl": 30,
        "type": "CNAME",
        "class": "IN",
        "name": "aaaaa",
        "data": "bbbbb"
      },
      {
        "ttl": 1800,
        "type": "CNAME",
        "class": "IN",
        "name": "bbbbb",
        "data": "ccccc"
      },
      {
        "ttl": 60,
        "type": "A",
        "class": "IN",
        "name": "ccccc",
        "data": "1.2.3.4"
      }
    ],
},
{
  "name": ...
...

It's basically a list of DNS resolution data.

For each question, there may be more than one answer. All I care about the is type: "A" record. After a little work and reading, I came up with this:

. | select(
    (.status = "NOERROR") and
    (.class = "IN") and
    (.data.answers? != null)) | select(.data.answers | map(select(.type == "A")))

This works to give me only the objects where the type is "A". However, because of the way that I built it, I lose the top level "name" value. The only thing returned are the actual answer objects themselves, the objects in the answers[]

The problem is, I need to access the original (top-level) name value. I'm missing something simple here, can someone give me a hand?

Thanks

EDIT: What I want to print out at the end is basically the top-level .name value and each .data value where the type == "A". There's a probably a much simpler way to do this, so if there is a completely different approach, I'm happy to hear that as well!

EDIT2: I originally thought this would be simpler and did:

. | select(
  (.status = "NOERROR") and
  (.class = "IN") and
  (.data.answers? != null) and
  (.data.answers[].type=="A")) | .

... but this returns the entire list of A, CNAME, and other types of values, as long as there is a single A present, it seems. So no luck there

Upvotes: 0

Views: 971

Answers (1)

oguz ismail
oguz ismail

Reputation: 50760

However, because of the way that I built it, I lose the top level "name" value

Stay in the top-level then.

.[]
| select(.class == "IN" and .status == "NOERROR")
| .name + ": " + (.data.answers[] | select(.type == "A") .data)?

Upvotes: 1

Related Questions