Martin
Martin

Reputation: 2611

jq process json where an element can be an array or object

The output from the tool I am using is creating an element in the json that is an object when there is only 1 item but an array when there is more than 1.

How do I parse this with jq to return the full list of names only from within content?

{
  "data": [
    {
      "name": "data block1",
      "content": {
        "name": "1 bit of data"
      }
    },
    {
      "name": "data block2",
      "content": [
        {
          "name": "first bit"
        },
        {
          "name": "another bit"
        },
        {
          "name": "last bit"
        }
      ]
    }
  ]
}

What I can't work out is how to switch depending on the type of content.

# jq '.data[].content.name' test.json
"1 bit of data"
jq: error (at test.json:22): Cannot index array with string "name"
# jq '.data[].content[].name' test.json
jq: error (at test.json:22): Cannot index string with string "name"

I am sure I should be able to use type but my jq-fu is not strong enough!

# jq '.data[].content | type=="array"' test.json
false
true

jq version 1.5

Upvotes: 2

Views: 1354

Answers (1)

peak
peak

Reputation: 117027

jq '.data[].content | if type == "array" then .[] else . end | .name?'

(The trailing ? is there just in case.)

More succinctly:

jq '.data[].content | .name? // .[].name?'

Upvotes: 4

Related Questions