如何在循环中使用 jq+shell 附加 json 数组?
How to append json array using jq+shell in a loop?
我可以像这样使用 jq 创建一个带有数组的 json 对象
echo '{"input":{"names":[]}}' | jq --arg val "alice" '.input.names[0] += $val'| jq --arg val "bob" '.input.names[1] += $val'
这给出了
{
"input": {
"names": [
"alice",
"bob"
]
}
}
现在我想在 shell 脚本中重新创建它,其中“名称”来自 shell 数组
#!/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
但我运行进入
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
您可以摆脱 shell 循环并使用一个 jq
调用:
names=( alice bob )
jq -n --arg names "${names[*]}" '{"input": {"names": ($names / " ") } }'
或
names=( alice bob )
printf '%s[=11=]' "${names[@]}" |
jq -sR '(. / "\u0000") as $names | { "input": { "names": $names } }'
您没有捕获迭代步骤的输出,因此您丢失了 jq
调用的输出并在下一个迭代步骤中重新开始。
这是一个 bash
解决方案,它使用 $(...)
捕获输出并使用 <<<
为下一个输出提供它。 (请注意,有更好的方法可以解决此问题,例如,无需循环,而是通过证明 jq
一次添加所有元素。)
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"
]
}
}
我可以像这样使用 jq 创建一个带有数组的 json 对象
echo '{"input":{"names":[]}}' | jq --arg val "alice" '.input.names[0] += $val'| jq --arg val "bob" '.input.names[1] += $val'
这给出了
{
"input": {
"names": [
"alice",
"bob"
]
}
}
现在我想在 shell 脚本中重新创建它,其中“名称”来自 shell 数组
#!/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
但我运行进入
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
您可以摆脱 shell 循环并使用一个 jq
调用:
names=( alice bob )
jq -n --arg names "${names[*]}" '{"input": {"names": ($names / " ") } }'
或
names=( alice bob )
printf '%s[=11=]' "${names[@]}" |
jq -sR '(. / "\u0000") as $names | { "input": { "names": $names } }'
您没有捕获迭代步骤的输出,因此您丢失了 jq
调用的输出并在下一个迭代步骤中重新开始。
这是一个 bash
解决方案,它使用 $(...)
捕获输出并使用 <<<
为下一个输出提供它。 (请注意,有更好的方法可以解决此问题,例如,无需循环,而是通过证明 jq
一次添加所有元素。)
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"
]
}
}