Given the following JSON containing 3 variables:
{
"variables": {
"AWS_ROLE": "DevOpsAccessRole",
"AWS_REGION": {
"description": "AWS region",
"value": "us-west-2",
"options": [
"us-west-2",
"us-east-1"
]
},
"ENVIRONMENT": {
"description": "Environment to deploy to",
"value": "dev",
"options": [
"dev",
"qa",
"prod"
]
}
}
}
My goal is to select only the variable names containing the description
field.
So the desired output is (don’t care about the order):
AWS_REGION
ENVIRONMENT
AWS_ROLE
should be left out since it does not contain the description
key.
I’ve initially tried:
jq -r '.variables | keys []'
Which returns:
AWS_ROLE
AWS_REGION
ENVIRONMENT
But I’m stuck removing the ones without description
.
Also tried:
jq -r '.variables |..| select(.description?)'
but the problem here is that I loose access to the variable names.
How can I do this in jq
?
>Solution :
Use to_entries
to get simultaneous access to both the .key
and the .value
, test the existence of a (sub-)key using has
, and use ?
to suppress errors if it is not an object (thus has no key, and would error out). Using the -r
flag gives you a raw-text output.
jq -r '.variables | to_entries[] | select(.value | has("description")?).key'
AWS_REGION
ENVIRONMENT
The same technique using keys
, iterated over and stored in a variable:
jq -r '.variables | keys[] as $k | .[$k] | select(has("description")?) | $k'