如何在没有完整路径的情况下将值添加到JSON数组?

时间:2020-05-25 05:41:50

标签: json jq

我在搜索了几个小时后无法解决的“ jq”问题。让我们以这个简单的JSON为例,将“ Category4”嵌套在“ Category2”中:

{
  "categories": [
    {
      "Id": 1,
      "Name": "Category1",
      "Children": []
    },
    {
      "Id": 2,
      "Name": "Category2",
      "Children": [
        {
          "Id": 4,
          "Name": "Category4",
          "Children": []
        }
      ]
    },
    {
      "Id": 3,
      "Name": "Category3",
      "Children": []
    }
  ]
}

我想在“ Category4”对象内添加“ Category5”子级,例如:

{
  "categories": [
    {
      "Id": 1,
      "Name": "Category1",
      "Children": []
    },
    {
      "Id": 2,
      "Name": "Category2",
      "Children": [
        {
          "Id": 4,
          "Name": "Category4",
          "Children": [
            {
              "Id": 5,
              "Name": "Category5",
              "Children": []
            }
          ]
        }
      ]
    },
    {
      "Id": 3,
      "Name": "Category3",
      "Children": []
    }
  ]
}

我可以通过以下方式使用“ Category4”对象的完整路径来实现:

jq --argjson a '[{"Id":5,"Name":"Category5","Children":[]}]' '.categories[1].Children[0].Children += $a' "myfile.json"

但是,如果我不知道“ Category4”的位置(可能位于根级别或嵌套在其他对象内部),如何获得相同的结果?这个命令是我最好的猜测:

jq --argjson a '[{"Id":5,"Name":"Category5","Children":[]}]' '.. | select(.Id?==4) | .Children += $a' "myfile"

,但它仅检索“ Category4”和“ Category5”对象(输出中缺少Category1、2和3)。我觉得我想念一些愚蠢的东西...

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

使用walk builtin将过滤器应用于任意深度的值,而无需更改整体结构。

walk(select(.Id? == 4) .Children += $a)

demo at jqplay.org