jq根据值更新JSONkey:value

Jq update JSON key:value based on value

我对 jq 还很陌生,想用它来更新具有新值的 AWS ECS 任务定义。 AWS cli returns 以下 json 响应,我想用 name 属性 CONFIG_URL 修改对象 "this is atest"。

{
  "family": "contentpublishing-task",
  "volumes": [],
  "containerDefinitions": [
    {
      "environment": [
        {
          "name": "TEST_ENV",
          "value": "TEST"
        },
        {
          "name": "CONFIG_URL",
          "value": "s3://stg-appcfg/config-20160729-1130.json"
        }
      ],
      "name": "contentpublishing",
      "mountPoints": [],
      "image": "contentpublishing:blah",
      "cpu": 512,
      "portMappings": [
        {
          "protocol": "tcp",
          "containerPort": 8081,
          "hostPort": 8080
        }
      ],
      "memory": 256,
      "essential": true,
      "volumesFrom": []
    }
  ]
}

尝试了以下查询

 cat test.json | jq 'select(.containerDefinitions[0].environment[].name=="CONFIG_URL").value|="this is atest"' 2>&1 

但已返回以下内容。如您所见,在最外面的 json 对象中添加了一个附加值键。

{
  "family": "contentpublishing-task",
  "volumes": [],
  "containerDefinitions": [
    {
      "environment": [
        {
          "name": "TEST_ENV",
          "value": "TEST"
        },
        {
          "name": "CONFIG_URL",
          "value": "s3://stg-appcfg/config-20160729-1130.json"
        }
      ],
      "name": "contentpublishing",
      "mountPoints": [],
      "image": "contentpublishing:blah",
      "cpu": 512,
      "portMappings": [
        {
          "protocol": "tcp",
          "containerPort": 8081,
          "hostPort": 8080
        }
      ],
      "memory": 256,
      "essential": true,
      "volumesFrom": []
    }
  ],
  "value": "this is atest"
}

您必须先select相应的环境节点才能设置值。您的查询不会更改上下文,因此它仍在根项上,因此您最终将新值添加到根项。

$ jq --arg update_name "CONFIG_URL" --arg update_value "this is a test" \
'(.containerDefinitions[].environment[] | select(.name == $update_name)).value = $update_value' input.json

这是一个使用 jq 的解决方案 Complex assignments

(
  .containerDefinitions[]
| .environment[]
| select(.name == "CONFIG_URL")
| .value
) |= "this is atest"