You can use the bash builtin read together with a process substitution connecting the output of jq to a FIFO:
read username < <(curl -s -X GET -H "Header:Value" http://127.0.0.1:8200/etc | jq -r '.data.value')
As long as you only need to assign a single jq value, the other proposed solutions are simplier.
The present solution with read is useful when you need to assign multiple keys to multiple shell variables in one shot; you then just need to use read var1 var2 var3 < <(...).
Here are more general snippets to assign jq output to shell variables, that can be very handy.
Two methods for single-line input (without loop):
IFS=$'\n' read -rd '' a b < <(echo '{"a":"1","b":"2"}' | jq -r '(.a, .b)'); declare -p a b
declare -- a="1"
declare -- b="2"
read a b < <(echo '{"a":"1","b":"2"}' | jq -r '[.[]] | @tsv'); declare -p a b
declare -- a="1"
declare -- b="2"
Note1: @tsv uses space delimiter; for values that may have spaces you can use the @csv format.
Note2: IFS=$'\n' read -rd '' a b < is assuming that no output lines are empty. If some json keys are empty, you can then use 'jq' without '--raw' and remove the "'s afterwards with a=${a:1:-1}, or you can use readarrayinstead of read (cf. example below).
Three methods for multi-lines input (with loop):
echo '[{"a":"1","b":"2"},{"a":"3","b":"4"}]' |
jq -r '.[] | {a, b} | [.[]] | @csv' |
while IFS= read -r i; do
IFS=, read -r a b <<< "$i"; a=${a:1:-1}; b=${b:1:-1}; declare -p a b;
done
declare -- a="1"
declare -- b="2"
declare -- a="3"
declare -- b="4"
echo '[{"a":"1","b":"2"},{"a":"3","b":"4"}]' |
jq -r '.[] | (.a, .b)' |
while IFS= read -r a; do
IFS= read -r b; declare -p a b;
done
declare -- a="1"
declare -- b="2"
declare -- a="3"
declare -- b="4"
echo '[{"a":"1","b":"2"},{"a":"3","b":"4"}]' |
jq -r '.[] | (.a, .b)' |
while readarray -n2 lines && [ ${#lines} -ne 0 ]; do
a="${lines[0]:0:-1}"; b="${lines[1]:0:-1}"; declare -p a b;
done
declare -- a="1"
declare -- b="2"
declare -- a="3"
declare -- b="4"