【问题标题】:JQ Loop over Bash array add elementsJQ循环遍历Bash数组添加元素
【发布时间】:2022-09-30 17:47:42
【问题描述】:

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

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

JSON 如下所示。我想更新水果大批。

  \"foods\": {
    \"perishable\": {
      \"fruit\": []

我会得到一个长度数组n, 例如:

fruit_array=(\"banana\" \"orange\")

它应该看起来像这样:

  \"foods\": {
    \"perishable\": {
      \"fruit\": [
        { 
          \"001\": {
            \"002\": \"banana\"
          }
        },
        { 
          \"001\": {
            \"002\": \"orange\"
          }
        }
      ]

有这样做的好方法吗?目前我正在尝试以下方法:

#!/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

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

但是,我知道这似乎有点狡猾,并怀疑有一个更清洁、更jq方法。

以前的 - 中止 - 尝试是这样的:

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

这产生了一个转义字符串,我对此无能为力,但至少暗示标准 bash 循环可能有一个更简洁的解决方案。

我错过了一些东西。

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

  • 键控是如何工作的? \"001\" --> 你想要两个领先的0 吗?或者它必须是 3 长?
  • 您的 JSON 模板似乎已损坏;我猜应该是{\"foods\": {\"perishable\": {\"fruit\": []}}}

标签: json bash jq


【解决方案1】:

JQ 可以自己做所有这些;你不需要循环或任何东西。

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

【讨论】:

    【解决方案2】:

    使用printf 一次创建整个 json 字符串:

    fruit_array=("banana" "orange")
    printf -v fruits '{"001": {"002": %s}},' "${fruit_array[@]}"
    $ echo $fruits
    {"001": {"002": banana}},{"001": {"002": orange}},
    

    然后将其添加到您的模板中删除最后一个逗号:

    $ echo ${fruits%,}
    {"001": {"002": banana}},{"001": {"002": orange}}
    

    “数字”也可以这样设置:

    fruit_array=("1 2 banana" "3 4 orange")
    printf '{"%.3d": {"%.3d": %s}},' ${fruit_array[@]}
    {"001": {"002": banana}},{"003": {"004": orange}},
    

    【讨论】:

      【解决方案3】:

      我想你可以为要添加到模板的内容构建表达式,然后在上面运行一次jq

      printf -v fruits '[{"001": {"002": "%s"}}],' "${fruit_array[@]}"
      fruits=${fruits%,}  # uglyness!
      jq ".foods.perishables.fruit += ${fruits//],[/,}" template.json > template_with_fruit.json
      

      【讨论】:

        【解决方案4】:

        如果将数组作为空格分隔的字符串传递,则可以像这样使用 JQ:

        jq --arg fruits "$fruit_array" \
            '.foods.perishable.fruit |= ($fruits | split(" ") | map({ "001": { "002": . } }))' input
        

        {
          "foods": {
            "perishable": {
              "fruit": [
                {
                  "001": {
                    "002": "banana"
                  }
                },
                {
                  "001": {
                    "002": "orange"
                  }
                }
              ]
            }
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-24
          • 2019-11-06
          相关资源
          最近更新 更多