0

这个问题是我之前问过的一个问题的扩展:在正确的部分添加 JSON 值

本质上,我有一个 json 文件“veggies.json”,如下所示:

{"plants":
  {"veggies":
    [
      {"section":"TUBERS",
        "values":
          [
            {"tuber":"potato","cookstyle":"fry"}
          ]
      },
      {"section":"LEGUMES",
        "values":
          [
            {"legume":"beans","cookstyle":"boil"},
            {"legume":"peanuts","cookstyle":"salted"}
          ]
      }
    ]
  }
}

我想添加另一个块茎“山药”,它可以有烹饪风格的“煮沸” - 这必须在 TUBERS 部分下,但独一无二。意思是,我只想在它不存在的情况下添加这个块茎 - 如果它已经存在,我只想用我传递的任何“cookstyle”替换它 - 它也可以是cookstyle:“mashed”。

从我之前的问题中,我已经有了使用“jq”工具的代码:

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

但是,这行代码在 TUBERS 部分下多次添加同一行 - 有什么方法可以唯一添加它(类似哈希的行为)

非常感谢提前。

4

3 回答 3

0

好的 - 事实证明我对这整件事想得太多了 - 也许它可以作为 jq 本身的单线,但由于我可以自由使用 shell,我只是检查是否存在“山药”,如果没有的话,添加它,如果有,请编辑它 - 像这样:

IS_YAM_PRESENT=`jq '(.plants.veggies[] | select(.section == "TUBERS") | .values[] | select(.tuber == "yam") | .cookstyle)' veggies.json`
if [ -z ${IS_YAM_PRESENT} ]
then
    jq '(.plants.veggies[] | select(.section == "TUBERS") | .values) |= . + [{ "tuber": "yam", "cookstyle": "boiled" }]' veggies.json
else
    jq '(.plants.veggies[] | select(.section == "TUBERS") | .values[] | select(.tuber == "yam")) |= { "tuber": "yam", "cookstyle": "boiled" }' veggies.json
fi

与往常一样,如果有人对此有更好的更“精致”和“更严格”的解决方案,我会很高兴看到它。

干杯! :)

于 2014-09-18T07:22:52.577 回答
0

这看起来应该可以工作,但它没有——如果没有“山药”,那么输出是空的。

jq '
  if (.plants.veggies[] | select(.section == "TUBERS") | .values)[] | select(.tuber == "yam")
  then . 
  else (.plants.veggies[] | select(.section == "TUBERS") | .values) += [{"tuber":"yam", "cookstyle":"mashed"}]    
  end
' veggies.json 
于 2014-09-16T15:42:43.047 回答
0

我认为Lakshminarayanan的解决方案非常接近。如果您不想要重复的山药(如果它已经在阵列中),您可以使用unique将其删除。例如

   (
       .plants.veggies[]
     | select(.section == "TUBERS")
     | .values

   ) |= (
          . + [ {"cookstyle": "boil", "tuber": "yam"} ]
          | unique
        )

或者也许考虑将逻辑放在一个单独的函数中,以便在它变得复杂时更容易管理。例如

def addyam:
     . + [ {"cookstyle": "boil", "tuber": "yam"} ]
   | unique
;

   (
       .plants.veggies[]
     | select(.section == "TUBERS")
     | .values

   ) |= addyam
于 2017-08-16T04:02:02.253 回答