使用jq进行非破坏性分配

时间:2018-02-15 11:23:27

标签: json jq

我收到了以下数据:

{
  "things": [
    {
        "name": "lkj",
        "something": [
            "hike"
        ],
        "more_data": "important",
        "other_stuff": "very important"
    },
    {
        "name": "iou",
        "different_more_data": "very important too",
        "more_different_data": [
            "even more"
        ]
    }
  ]
}

每个things都有一个名为“name”的ID,jq我可以编辑它:

jq '(.things[]) |= {name,something:["changed"]}'

{
  "things": [
    {
        "name": "lkj",
        "something": [
            "changed"
        ]
    },
...

不幸的是,我失去了在分配操作右侧未声明的所有内容。

有没有办法在不丢失数据的情况下进行分配?所以结果是这样的:

{
  "things": [
    {
        "name": "lkj",
        "something": [
            "changed"
        ],
        "more_data": "important",
        "other_stuff": "very important"
    },
    {
        "name": "iou",
        "something": [
            "changed"
        ],
        "different_more_data": "very important too",
        "more_different_data": [
            "even more"
        ]
    }
  ]
}

2 个答案:

答案 0 :(得分:0)

使用jq' map 功能:

jq '.things |= map(.something = ["changed"])' jsonfile
  • map(x) - 为输入数组的每个项目应用指定的过滤器x
  • .something = ["changed"] - 将键something设置为数组["changed"]作为值的对象

输出:

{
  "things": [
    {
      "name": "lkj",
      "something": [
        "changed"
      ],
      "more_data": "important",
      "other_stuff": "very important"
    },
    {
      "name": "iou",
      "different_more_data": "very important too",
      "more_different_data": [
        "even more"
      ],
      "something": [
        "changed"
      ]
    }
  ]
}

答案 1 :(得分:0)

您只需修改查询即可:

 .things[] |= (.something = ["changed"])

您还可以在RHS表达式中使用|=(或其中一个兄弟姐妹,例如+=)代替=,例如

.things[] |= (.something += ["changed"])

如果您想更新部分项目,但不是所有项目,您仍然可以使用上述表格。一种直截了当的方法是使用if ... then ... else ... end,例如:

 .things[] |= (if .name == "lkj" then .something = ["changed"] else . end)

select

的LHS上使用|=

jq(或自1.4版以来至少是jq)确实支持在select的LHS上使用|=,例如

(.things[] | select(.name=="lkj")) |= (.something += ["changed"])