在正确的部分中添加JSON值

时间:2014-09-08 17:19:30

标签: json shell jq

我的json文件'veggies.json'如下:

{"plants":
  {"veggies":
    [
      {"section":"TUBERS",
        "values":
          [
            {"tuber":"potato","type":"stem"}
          ]
      },
      {"section":"LEGUMES",
        "values":
          [
            {"legume":"beans"},
            {"legume":"peanuts"}
          ]
      }
    ]
  }
}

我想添加另一个“山药”的块茎“山药” - 这必须在TUBERS部分下。

我刚刚开始使用JSON,我一直在用各种各样的jq命令打破我的头脑,但是没有多大用处。

我尝试使用以下命令读取值[0]的值,但我似乎无法列出任何内容:

jq -r "[.[] | select(.plants.veggies.section == \"TUBERS\") | .plants.veggies.values.tuber]" veggies.json

基本上,我正在努力实现这一点 - 如果植物部分是TUBERS,添加块茎“yam”,其类型为“root”

有人可以帮帮我吗?

哦,我坚持使用jq 1.2版,如果这很重要(向后兼容性和所有这些东西)。

提前非常感谢。

2 个答案:

答案 0 :(得分:2)

没关系 - 经过一些更多的破解之后,我想我明白了:

cat veggies.json | jq '.plants.veggies[] | select(.section == "TUBERS") | .values |= . + [{ "type": "root", "tuber": "yam" }]'

这似乎符合我的要求:

{
  "values": [
    {
      "type": "stem",
      "tuber": "potato"
    },
    {
      "tuber": "yam",
      "type": "root"
    }
  ],
  "section": "TUBERS"
}

如果有人能够进一步优化这一点,我也非常渴望了解这一点。

答案 1 :(得分:2)

请改为尝试:

jq '(.plants.veggies[] | select(.section == "TUBERS") | .values) |= . + [{"type": "root", "tuber": "yam"}]' veggies.json

这会运行一个子过滤器:选择veggies数组的元素,找到具有匹配部分的元素并产生值varray。然后它将对象追加到values数组。

这与您自己的答案中的过滤器基本相同,只有一个关键区别:因为您实际上没有从主输入数据中过滤掉任何内容,它将打印出整个JSON文档(而不仅仅是修改后的文档)一部分)。我不确定这对您是否有好处,但这使得在脚本中整体修改文档变得非常容易。

(在jq 1.3上测试)