如果对应于给定键的值以指定字符串开头,则使用jq更新JSON文档中的对象

时间:2017-06-07 10:41:20

标签: json bash shell jq

我有给定的JSON并希望更改所有元素的id值,该值以test元素中的name开头:

{
    "other-value": "some-id",
    "values": [
        {
            "name": "test-2017-12-01",
            "id": "1"

        },
        {
            "name": "othert",
            "id": "2"
        }

    ]
}

以下jq命令有效jqplay

jq (.values[] | select(.name == "test-afs").id) |= "NEWID"

但是当我用startswith尝试时,它会停止工作,我错过了什么? jqplay

(.values[] | select(.name | startswith("test")).id) |= "NEWID" 
  

jq:error(at:14):在尝试访问元素" id"附近的路径表达式无效{" name":" test-afs"," id":" id"}   退出状态5

2 个答案:

答案 0 :(得分:4)

您也可以使用map,如下所示:

jq '(.values)|=(map((if .name|startswith("test") then .id="NEWID"  else . end)))' file

输出:

{
  "other-value": "some-id",
  "values": [
    {
      "name": "test-2017-12-01",
      "id": "NEWID"
    },
    {
      "name": "othert",
      "id": "2"
    }
  ]
}

答案 1 :(得分:2)

请注意,自jq 1.5发布以来,jq已得到增强,可支持以前失败的查询。例如,使用当前的主人'版本:

jq -c '(.values[] | select(.name | startswith("test")).id) |= "NEWID"'
{"other-value":"some-id","values":[{"name":"test-2017-12-01","id":"NEWID"},{"name":"othert","id":"2"}]}

使用早期版本的jq,如果/ then / else / end可以在这种情况下使用,如下所示:

.values[] |= if .name | startswith("test") then .id = "NEWID" else . end

如果使用map,则极简表达式为:

.values |= map(if .name|startswith("test") then .id = "NEWID" else . end)