How to convert a JSON object to key=value format in jq?

without jq, I was able to export every item in json using grep and sed but this will work for simple cases only where we have key/value pairs

for keyval in $(grep -E '": [^\{]' fileName.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
    echo "$keyval"
done

here's a sample response:

❯ for keyval in $(grep -E '": [^\{]' config.dev.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
    echo "$keyval"       
done
"env"="dev"
"memory"=128
"role"=""
"region"="us-east-1"

You could try:

jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json

Here's a demo:

$ cat test.json
{
    "var": 1,
    "foo": "bar",
    "x": "test"
}
$ jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json
foo=bar
var=1
x=test

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.307014Z
VERSION=1
SESSIONTOKEN=ABcdEFghIJ....
ACCESSKEYID=ABCDEFGHIJ.....
SECRETACCESSKEY=AbCdEfGhI.....

References

  • https://github.com/oktadeveloper/okta-aws-cli-assume-role
  • https://github.com/stedolan/jq/issues/492

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=1
b=2
c=3

Tags:

Bash

Json

Jq