16

I have this input data:

[
  {
    "attributes": {
      "created": "2021-10-18T12:02:39+00:00",
      "enabled": true,
      "expires": null,
      "notBefore": null
    },
    "contentType": null,
    "id": "https://kjkljk./secrets/-/1",
    "managed": null,
    "name": "pw",
    "tags": {}
  },
  {
    "attributes": {
      "created": "2021-10-18T12:06:16+00:00",
      "enabled": true,
      "expires": null,
      "notBefore": null
    },
    "contentType": "",
    "id": "https://kjklj./secrets/-/2",
    "managed": null,
    "name": "pw",
    "tags": {}
  }
]

I need to use jq to extract the id values into a new array where enabled is set to true. this is what I have so far:

.[] | select(any(.attributes; .enabled== true)) | {id} 

but it only results in this:

{
  "id": "https://kjkljk./secrets/-/1"
}
{
  "id": "https://kjklj./secrets/-/2"
}

how can i make these two objects into an array of strings instead?

[
  "id": "https://kjkljk./secrets/-/1",
  "id": "https://kjklj./secrets/-/2"
]
1
  • 1
    [ "id": "https://kjkljk./secrets/-/1", "id": "https://kjklj./secrets/-/2" ] isn't valid JSON. You said "array of strings", so did you mean [ "https://kjkljk./secrets/-/1", "https://kjklj./secrets/-/2" ]? Commented Dec 12, 2021 at 7:08

4 Answers 4

25

Use map instead of .[] to retain the array:

map(select(any(.attributes; .enabled)) | {id})
[
  {"id": "https://kjkljk./secrets/-/1"},
  {"id": "https://kjklj./secrets/-/2"}
]

Demo

Note that this produces an array of objects [{…},{…}], what I believe is what you asked for although in your desired output you are missing the curly object braces { }. To make an "array of strigs" instead, use .id instead of {id} like so

map(select(any(.attributes; .enabled)) | .id)
[
  "https://kjkljk./secrets/-/1",
  "https://kjklj./secrets/-/2"
]

Demo

(Also, you can use .enabled instead of .enabled == true)

Sign up to request clarification or add additional context in comments.

Comments

11

Something like:

$ jq '[.[] | select(.attributes.enabled) | .id]' input.json
[
  "https://kjkljk./secrets/-/1",
  "https://kjklj./secrets/-/2"
]

1 Comment

Can be shortened and made more readable so: map(select(.attributes.enabled).id)
2

This should work:

map(select(any(.attributes; .enabled == true)) | .id)

Explanation: Rather than splitting the array with .[], the map() function leaves the array structure intact but operates on the elements. Using .id rather than {id} avoids creating a dictionary for each selected value.

If I understand right, you could also replace any(.attributes; .enabled == true) with just .attributes.enabled == true.

Comments

2

Like already written in the answers, comments before, your wished output is not valid json.

So you have to options. I pasted your input file in SO-70302009.json

  1. Wrap the id line as objects jq 'map({id: select(any(.attributes; .enabled)) | .id})' "./SO-70302009.json" to get
[
  {
    "id": "https://kjkljk./secrets/-/1"
  },
  {
    "id": "https://kjklj./secrets/-/2"
  }
]
  1. Make an array of ids jq '{ ids: map(select(any(.attributes; .enabled)) | .id) }' "./SO-70302009.json" to get
{
  "ids": [
    "https://kjkljk./secrets/-/1",
    "https://kjklj./secrets/-/2"
  ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.