How to use jq to selectively update JSON array, referring to parent properties

孤者浪人 提交于 2020-02-08 02:39:46

问题


I'm trying to use jq to selectively change a single property of an object nested in an array, keeping the rest of the array intact. The generated property value needs to refer up to a property of the parent object.

As an example, take this array:

[
  {
    "name": "keep_me"
  },
  {
    "name": "leave_unchanged",
    "list": [
      {
        "id": "1",
        "key": "keep_this"
      }
    ]
  },
  {
    "name": "a",
    "list": [
      {
        "id": "2",
        "key": "also_keep_this"
      },
      {
        "id": "42",
        "key": "replace_this"
      }
    ]
  }
]

I want to change the value of the last key (replace_this), using the name property of the parent object to generate a value like generated_value_for_a_42.

The key problem here seems to be leaving the rest of the array unmodified, while updating specific elements. But the need to refer 'up the tree' to a parent property complicates matters. I tried wrapping changes in parentheses to keep untouched elements, but then had trouble with variable binding (using as) to the right scope, for accessing the parent property. So I either ended up discarding parts of the array or objects, or getting errors about the variable binding.


回答1:


This answer helped me in the right direction. The important learnings were to use |= in the right place, and have the filters wrapped in if p then f else . to keep the unchanged elements.

The following jq script solves the task:

map(.name as $name |
    if has("list")
    then .list |= map(if .key | contains("keep") | not
                      then .key = "generated_value_for_" + $name + "_" + .id
                      else .
                      end)
    else .
    end)


来源:https://stackoverflow.com/questions/60073976/how-to-use-jq-to-selectively-update-json-array-referring-to-parent-properties

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!