melon@machine: ~/$ cat /tmp/test.json
[
"One Entry Here",
"Two Entry Here",
"Three Entry Here",
"Four Entry Here"
]
melon@machine: ~/$ jq -sr '.[]| @sh' /tmp/test.json
'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here'
melon@machine: ~/$ BANANA=( 'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here' )
melon@machine: ~/$ echo ${BANANA[1]}
Two Entry Here
The above shows the expected behavior, and shows me manually setting $BANANA
to the output of the jq
command.
This behavior changes if the variable uses command substitution instead:
melon@machine: ~/$ BANANA=( $(jq -sjr '.[]| @sh' /tmp/test.json) )
melon@machine: ~/$ echo ${BANANA[1]}
melon@machine: ~/$ echo ${BANANA[0]}
'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here'
While it is true that I am trying to convert a JSON array into a BASH array to iterate over, and there are other suggested methods, my question is Why is the behavior different here when using command substitution, and is there anything that I can do to have the command substitution behave like when I manually copy and paste the jq
output into the variable myself?
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
melon@machine: ~/$ mapfile -t BANANA < <(jq '.[]' /tmp/test.json)
melon@machine: ~/$ echo ${BANANA[0]}
"One Entry Here"
melon@machine: ~/$ echo ${BANANA[1]}
"Two Entry Here"
mapfile
works, but I'm still curious about the difference when using command substitution.
Even after adding the -j
flag to jq
to suppress ending newline, the results are the same.
BANANA[0]
to be'One
andBANANA[1]
to beEntry
i.e. the the (unquoted) command substitution would be split on whitespace. Your results are more consistent with a quoted command substitution (or with an empty or unsetIFS
)jq
may be causing the difference, and it seems that it may be providing a newline at the end of the output, which may be causing a difference. Simply adding-j
flag to suppress the newline doesn't seem to help. Thank you for your thoughts.mapfile -t BANANA < <(jq -r '.[]' /tmp/test.json)
mapfile
, I was using the samejq
flags and now that I've adjusted those,mapfile
does work.PATH=something
and then wonder why your script is broken.