【问题标题】:Adding/Appending objects to a nested JSON array via jq in a bash script通过 bash 脚本中的 jq 将对象添加/附加到嵌套 JSON 数组
【发布时间】:2021-03-16 13:11:22
【问题描述】:

这是我之前帖子的后续。

我已经能够在单个 JSON 数组上动态添加和追加对象。 但是,在嵌套数组列表上尝试相同时我遇到了困难。

能够通过海绵做到这一点:

{
  "profiles": [
    {
      "name": "Paul",
      "car": "Nissan",
      "colour": "Black"
    }
  ]
}

追加:

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": "Joe",
      "car": "BMW",
      "colour": "Blue"
    },
    {
      "name": "Paul",
      "car": "Nissan",
      "colour": "Black"
    }
  ]
}

我正在尝试做的是这样的:

{
  "key1": "One",
  "key2": "Two",
  "profiles": [
    {
      "name": "Joe",
      "car": "BMW",
      "colour": "Black"
    },
    {
      "name": "Sarah",
      "car": "Mercedes",
      "colour": "Red"
    }
  ],
  "key3": "Three",
  "list2": [
    "list2"
  ],
  "key4": "Four",
  "list3": [
    {
      "key5": "Five"
    }
  ]
}

基本上想将对象添加/追加到嵌套的 profiles 数组中。

在我的问答和循环之后一直在使用以下内容:

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

然后将输出读取到要在我的最终 jq 命令中使用的变量:

profiles=`cat profiles.json`

但是,这个最终的 jq 没有正确输出。

jq -n --arg key1 "$key1" --arg key1 "$key2" --arg profiles "$profiles" --arg key3 "$key3" --arg key4 "key4" --arg key5 "key5" '{$key1, $key2, "profiles": $profiles, $key3, "list2": ["list2"], $key4, "list3": [{$key5}]}' > new_model.json

即使我改成:

"profiles": [.profiles],

这给了null:

{
  "key1": "One",
  "key2": "Two",
  "profiles": [
    null
  ],
  "key3": "Three",
  "list2": [
    "list2"
  ],
  "key4": "Four",
  "list3": [
    {
      "key5": Five
    }
  ]
}

考虑到其他键*值是动态添加的,不是固定的;有人对我如何正确添加/附加或输入profiles.json到nested profiles数组有任何想法吗?

最好排除profiles.json输出的开始和结束括号{}。

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

可能在我进行的每个问答块更新文件之后使用 jq 和海绵(如对单个数组所做的那样),删除 -n 标志等? 由于更多的移动部件以及配置文件数组嵌套在其他动态添加的键值中,因此对逻辑有些困惑。

非常感谢

【问题讨论】:

  • 有了你需要的所有处理,在某一时刻,编写一个简短的 Python 脚本并从 bash 调用它会更容易......
  • 这是真的,尽管我的目标是在 bash 中完全编写脚本。谢谢
  • 好吧,您已经不得不调用jq,它有自己的“语言”...在大多数 Linux 发行版 jq 中通常需要安装 IIRC,而 Python 几乎总是开箱即用.
  • 谢谢大家。作为最后一步,我能够在我的 bash 脚本中附加和调用 python 脚本。干杯

标签: arrays json bash append jq


【解决方案1】:

当没有其他键时,存在其他键的事实不会使您使用的策略无效。

据我所知,您的问题始于使用 bash 变量来存储结果:

profiles=`cat profiles.json`

这本身当然是无害的(至少如果文件足够小的话),但事情会从那里走下坡路。例如,当你写:

 --arg profiles "$profiles" 

jq 变量 $profiles 现在包含一个 JSON 字符串,这不是您想要的。您可以使用--argjson 将这只兔子从它的兔子洞里赶下来,但目的是什么?

【讨论】:

  • --argjson 几乎返回了我想要的。但我明白你的意思;它返回一个额外的无根据的"profiles": {
  • 开始工作了!谢谢@peak,您再次为我指明了正确的方向。你会碰巧知道如何在同一个 jq 命令下从某些输出值中删除引号吗?不是所有的,只是整数,即。假设key5 是一个整数"5"。我尝试使用-r,但没有任何效果。
  • 要将数字字符串转换为数字,可以使用tonumber。您可能会发现以下习语很有用:(tonumber? // .)
  • 谢谢@peak。遇到了一些麻烦,但最终让它输出了我需要的东西。
猜你喜欢
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多