JQ 在 Bash 数组上循环添加元素

ext*_*int 1 bash json jq

我似乎无法找到答案,但已经看到足够多的东西,知道可能有更好的方法来做我想做的事情。

问题:我有一个 bash 数组。对于 bash 数组中的每个元素,我想更新一个 JSON 数组。

JSON 如下所示。我想更新水果数组。

  "foods": {
    "perishable": {
      "fruit": []
Run Code Online (Sandbox Code Playgroud)

我将得到一个长度为n的数组,例如:

fruit_array=("banana" "orange")
Run Code Online (Sandbox Code Playgroud)

它应该看起来像这样:

  "foods": {
    "perishable": {
      "fruit": [
        { 
          "001": {
            "002": "banana"
          }
        },
        { 
          "001": {
            "002": "orange"
          }
        }
      ]
Run Code Online (Sandbox Code Playgroud)

有没有一个好的方法来做到这一点?目前我正在尝试以下操作:

#!/bin/bash

fruit_array=("banana" "orange")

for fruit in "${fruit_array[@]}"; do
   jq \
   --arg fruit $fruit \
   '.foods.perishables.fruit += [{"001": {"002": $fruit}}]' \
   template.json > template_with_fruit.json
done
Run Code Online (Sandbox Code Playgroud)

这不起作用的明显原因是模板正在被重新读取,但我已经搞砸了让它消耗上一次迭代的输出,但最后什么也没有出现。我只能更新模板一次。

然而,我知道这似乎有点狡猾,并怀疑有一种更干净、更jq 的方式。

之前的一次失败的尝试是这样的:

jq \
--argjson fruit "$(printf '{"001": {"002": "%s"}}\n' \"${fruit_array[@]}\" | jq -nR '[inputs]')" \
'.foods.perishables.fruit += $fruit' \
Run Code Online (Sandbox Code Playgroud)

这产生了一个转义字符串,我无法对其执行任何操作,但至少暗示标准 bash 循环可能有一个更简洁的解决方案。

我缺少一些东西。

一如既往,任何帮助将不胜感激。

ogu*_*ail 6

JQ 可以自己完成这一切;你不需要循环或任何东西。

jq '.foods.perishable.fruit += (
  $ARGS.positional
  | map({"001": {"002": .}})
)' template.json --args "${fruit_array[@]}" >template_with_fruit.json
Run Code Online (Sandbox Code Playgroud)