I can create a json object with an array using jq like this
echo '{"input":{"names":[]}}' | jq --arg val "alice" '.input.names[0] = $val'| jq --arg val "bob" '.input.names[1] = $val'
which gives
{
"input": {
"names": [
"alice",
"bob"
]
}
}
Now I want to recreate this in a shell script where "names" come from a shell array
#!/bin/sh
names=( alice bob )
ITER=0
for i in "${names[@]}"
do
echo '{"input":{"names":[]}}' | jq --arg val "$i" '.input.names[$ITER] = $val'
echo ${I} ${ITER}
ITER=$(expr $ITER 1)
done
but I run into
jq: error: $ITER is not defined at <top-level>, line 1:
.input.names[$ITER] = $val
jq: 1 compile error
0
jq: error: $ITER is not defined at <top-level>, line 1:
.input.names[$ITER] = $val
jq: 1 compile error
1
CodePudding user response:
You could get rid of the shell and use one jq
call:
names=( alice bob )
jq -n --arg names "${names[*]}" '{"input": {"names": ($names / " ") } }'
or
name=( alice bob )
printf '%s\0' "${names[@]}" |
jq -sR '(. / "\u0000") as $names | { "input": { "names": $names } }'
CodePudding user response:
You don't capture the output of an iteration step, so you lose the output from the jq
call and start all over again in the next iteration step.
Here's a bash
solution which captures the output using $(...)
and provides it for the next using <<<
. (Note that there are better ways to solve this problem, e.g. without looping but by proving jq
all elements to be added at once.)
json='{"input":{"names":[]}}'
for i in alice bob
do json="$(jq --arg val "$i" '.input.names = [$val]' <<< "$json")"
done
echo "$json"
{
"input": {
"names": [
"alice",
"bob"
]
}
}