'JQ map objects to array
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"
]
Solution 1:[1]
Use map
instead of .[]
to retain the array:
map(select(any(.attributes; .enabled)) | {id})
[
{"id": "https://kjkljk./secrets/-/1"},
{"id": "https://kjklj./secrets/-/2"}
]
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"
]
(Also, you can use .enabled
instead of .enabled == true
)
Solution 2:[2]
Something like:
$ jq '[.[] | select(.attributes.enabled) | .id]' input.json
[
"https://kjkljk./secrets/-/1",
"https://kjklj./secrets/-/2"
]
Solution 3:[3]
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
.
Solution 4:[4]
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
- 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"
}
]
- 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"
]
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | pmf |
Solution 2 | Shawn |
Solution 3 | Gordon Davisson |
Solution 4 | KargWare |