How to convert a JSON object to key=value format in jq?
Is there any way i can do this recursively?
Here is a function which might do what you want:
# Denote the input of recursively_reduce(f) by $in.# Let f be a filter such that for any object o, (o|f) is an array.# If $in is an object, then return $in|f;# if $in is a scalar, then return [];# otherwise, collect the results of applying recursively_reduce(f)# to each item in $in.def recursively_reduce(f): if type == "object" then f elif type == "array" then map( recursively_reduce(f) ) | add else [] end;
Example: emit key=value pairs
def kv: to_entries | map("\(.key)=\(.value)");[ {"a":1}, [[{"b":2, "c": 3}]] ] | recursively_reduce(kv)#=> ["a=1","b=2","c=3"]
UPDATE: After the release of jq 1.5, walk/1 was added as a jq-defined built-in. It can be used with the above-defined kv, e.g. as follows:
walk(if type == "object" then kv else . end)
With the above input, the result would be:
[["a=1"],[[["b=2","c=3"]]]]
To "flatten" the output, flatten/0 can be used. Here is a complete example:
jq -cr 'def kv: to_entries | map("\(.key)=\(.value)"); walk(if type == "object" then kv else . end) | flatten[]'
Input:
[ {"a":1}, [[{"b":2, "c": 3}]] ]
Output:
a=1b=2c=3
Incidentally, building off of @aioobe's excellent answer. If you need the keys to be all upper case you can use ascii_upcase
to do this by modifying his example:
jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'
Example
I had a scenario similar to yours but wanted to uppercase all the keys when creating environment variables for accessing AWS.
$ okta-credential_process arn:aws:iam::1234567890123:role/myRole | \ jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'EXPIRATION=2019-08-30T16:46:55.307014ZVERSION=1SESSIONTOKEN=ABcdEFghIJ....ACCESSKEYID=ABCDEFGHIJ.....SECRETACCESSKEY=AbCdEfGhI.....