Jq обновить ключ JSON: значение на основе значения

Я новичок в jq и хотел использовать его для обновления определения задачи AWS ECS с новым значением. AWS cli возвращает следующий ответ json, и я хотел бы изменить объект с name свойством CONFIG_URL с value «это атест».

{
  "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"
}

person shaytac    schedule 01.08.2016    source источник


Ответы (2)


Перед установкой значения необходимо выбрать соответствующий узел среды. Ваш запрос не изменяет контекст, поэтому он все еще находится в корневом элементе, поэтому в конечном итоге вы добавляете новое значение в корень.

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

Вот решение, которое использует jq Сложные задания

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