【问题标题】:Adding/appending objects to a newly created json array with same keys via jq in bash script通过 bash 脚本中的 jq 将对象添加/附加到具有相同键的新创建的 json 数组
【发布时间】:2021-03-13 09:16:28
【问题描述】:

我在尝试从同一个 bash 脚本对新创建的 JSON 数组/文件迭代地追加新值时遇到了困难。 考虑以下简单的脚本 sn-p:

echo "Enter name: "
read name
echo "Enter Car Model: "
read car
echo "Enter Colour: "
read colour

echo
jq -n --arg name "$name" --arg car "$car" --arg colour "$colour" '{"profiles":[{"name": $name, "car": $car, "colour": $colour}]}' > model.json
echo
cat model.json | jq .

这个输出:

Enter name:
Joe
Enter Car Model:
BMW
Enter Colour:
Red

{
  "profiles": [
    {
      "name": "Joe",
      "car": "BMW",
      "colour": "Red"
    }
  ]
}

我希望它最终做的事情是这样的,动态的:

Enter name:
Joe
Enter Car Model:
BMW
Enter Colour:
Red

{
  "profiles": [
    {
      "name": "Joe",
      "car": "BMW",
      "colour": "Red"
    },
    {
      "name": "Peter",
      "car": "Nissan",
      "colour": "White"
    }
  ]
}

等等……

我知道我需要在第一组 key:value 条目之后使用循环,但是我将如何附加到新创建的 model.json 文件而不是通过 jq 在 bash 脚本中覆盖初始值?

非常感谢

【问题讨论】:

    标签: arrays json bash append jq


    【解决方案1】:

    要附加对象,可以使用成语:

    .profiles += [...]
    

    由于 jq 处理null 的友好方式,上述方法最初也可以工作。

    顺便说一句,您可以缩写键值对,例如

    "name": $name
    

    只是变量名:

    $name
    

    示例

    为了统一起见,使用null 预填充model.json 可能是有意义的,例如

    echo null > model.json
    

    然后你可以统一调用 jq (不带 -n 选项),例如

    jq --arg name "$name" --arg car "$car" --arg colour "$colour" '
      .profiles += [{ $name, $car, $colour}]
    ' model.json | sponge model.json
    

    警告:使用sponge 覆盖输入文件而不采取预防措施有其风险,尽管在这种情况下它们似乎很小。

    【讨论】:

    • 喜欢这个? jq -n --arg name "$name" --arg car "$car" --arg colour "$colour" '.profiles += [{$name, $car, $colour}]' > model.json 因此,当我在 jq 命令和第一组 q&a 之间添加循环时,上述内容有效但不附加。只需覆盖第一组值。
    • 即使我用| .profiles += [{$name, $car, $colour}]' 管道上面的内容返回相同的一组值:`` { "profiles": [ { "name": "Paul", "car": "Datson" , "colour": "Brown" }, { "name": "Paul", "car": "Datson", "colour": "Brown" } ] } ``` 取最后一个条目两次。
    • 从 model.json 读取时,您应该删除 -n 选项
    • 谢谢高峰。我已经使用了您概述的方法,不幸的是,代码仍在输出一组值(我输入的最后一组条目)。无论我通过循环输入多少次值,都只会输出一组。我在上面的代码中看到了逻辑,但不确定我哪里出错了。
    • 您确定已删除 -n 选项吗?也许您应该先尝试最简单的情况,而不使用海绵。添加 jq debug 语句以查看发生了什么。
    【解决方案2】:

    使用了上面的方法,仍然没有追加: 即。

    Enter name:
    Joe
    Enter Car Model:
    BMW
    Enter Colour:
    Blue
    
    Add a new entry? (y/n):  y
    Enter name:  
    Paul
    Enter Car Model:  
    Nissan
    Enter Colour:  
    Black
    
    Add a new entry? (y/n):  n
    
    
    
    {
      "profiles": [
        {
          "name": "Paul",
          "car": "Nissan",
          "colour": "Black"
        }
      ]
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      相关资源
      最近更新 更多