1

I would like to below code to output
KNOCK_KNOCK="Who is there?"

TEST_FILE='{
  "KNOCK_KNOCK": "Who is there?"
}'
for s in $(echo $TEST_FILE | jq -r "to_entries|map(\"\ 
(.key)=\(.value|tostring)\")|.[]" ); do
    echo $s
done

I got the loop from this post: Exporting JSON to environment variables

and cannot figure out how to modify to get my expected output. The problem seems to be the spaces in the .value

For the following test case I get the expected results:

TEST_FILE='{
  "KNOCK_KNOCK": "Whoisthere?",
  "POSTGRES_URI": "postgress://user:pass@testdb.com",
  "WILL": "I.AM"
}'
for s in $(echo $TEST_FILE | jq -r "to_entries|map(\"\(.key)=\ 
(.value|tostring)\")|.[]" ); do
    echo $s
done

KNOCK_KNOCK=Whoisthere?
POSTGRES_URI=postgress://user:pass@testdb.com
WILL=I.AM

I went with the following solution, which works for me, but the accepted answer is ok.

TEST_FILE='{
  "KNOCK_KNOCK": "Who is there?"
}'
echo $TEST_FILE | sed 's_[{}]__'| sed 's_: _=_' | sed 's_  _export _'
peak
  • 105,803
  • 17
  • 152
  • 177

2 Answers2

4

One of many possibilities:

jq -r 'to_entries[] | [.key,.value] | join("=")' <<< "$TEST_FILE"

It would probably be advisable to use @sh as well:

$ echo $'{"KNOCK_KNOCK": "Who \'is\' there?"}'
  | jq -r 'to_entries[] | [.key,(.value|@sh)] | join("=")'
KNOCK_KNOCK='Who '\''is'\'' there?'

$ KNOCK_KNOCK='Who '\''is'\'' there?'
$ echo "$KNOCK_KNOCK"
Who 'is' there?
$ 

Note also that if you are going to use $TEST_FILE, the double-quotes might be necessary.

peak
  • 105,803
  • 17
  • 152
  • 177
  • Strictly speaking, the quotes are only necessary to work around various bugs in here-string handling in earlier versions of `bash`. 4.3 (and to a greater extent 4.4) appears to have resolved those problems, allowing the here string to be left unquoted. – chepner Oct 27 '18 at 20:57
  • For anyone using this answer, note that quotes aren't escaped. – Jose Diaz-Gonzalez Oct 07 '21 at 20:57
2

You almost got it but you can do this without a loop with this line:

$ echo '{"KNOCK_KNOCK": "Who is there?"}' | jq -r 'to_entries[] | .key + "=\"" + (.value|tostring) + "\""'
KNOCK_KNOCK="Who is there?"

Explanation

to_entries transforms your object to an array of objects like this:

$ echo '{"KNOCK_KNOCK": "Who is there?"}' | jq -r 'to_entries'                   
[
  {
    "key": "KNOCK_KNOCK",
    "value": "Who is there?"
  }
]

You can then take each array element with the [] and use the key and value field to do simple string concatenation using the + operator.

Friedrich Große
  • 2,383
  • 19
  • 19