The first two attempts at the end of the question do not work because they rely on the shell splitting the output of jq
on whitespace. Since newline is one type of whitespace, you lose the newlines (and tabs and the original spaces) in the data.
The attempts additionally fail to quote the string data, so you would get filename globbing happening if any string contained filename globbing characters.
The last attempt fails for similar reasons but additionally does not properly decode the data, leaving encoded newlines in place.
Using the built-in @sh
operator in jq
to quote the data and build an array assignment:
eval "$( jq -r '"fruits=(" + (map(.name)|@sh) + ")"' fruits.json )"
For the given JSON data, this would cause the following assignment to be evaluated by the current shell, creating the array fruits
:
fruits=('apple' 'banana
fofanna' 'my kiwi')
After evaluating that statement,
$ printf '<%s>\n' "${fruits[@]}"
<apple>
<banana
fofanna>
<my kiwi>
As an alternative, the following would append each name
element's value to the shell array:
$ jq -r '"fruits+=(" + (.[].name | @sh) + ")"' fruits.json
fruits+=('apple')
fruits+=('banana
fofanna')
fruits+=('my kiwi')
$ unset -v fruits
$ eval "$(jq -r '"fruits+=(" + (.[].name | @sh) + ")"' fruits.json)"
$ printf '<%s>\n' "${fruits[@]}"
<apple>
<banana
fofanna>
<my kiwi>