'How to append json array using jq+shell in a loop?

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


Solution 1:[1]

You could get rid of the shell loop and use one jq call:

names=( alice bob )
jq -n --arg names "${names[*]}" '{"input": {"names": ($names / " ") } }'

or

names=( alice bob )
printf '%s\0' "${names[@]}" |
jq -sR '(. / "\u0000") as $names | { "input": { "names": $names } }'

Solution 2:[2]

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"
    ]
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 pmf