Изменение массива значений ключа в JSON JQ - PullRequest
0 голосов
/ 04 января 2019

В случае, если у меня оригинальный JSON выглядит следующим образом:

{
  "taskDefinition": {
    "containerDefinitions": [
      {
        "name": "web",
        "image": "my-image",
        "environment": [
          {
            "name": "DB_HOST",
            "value": "localhost"
          },
          {
            "name": "DB_USERNAME",
            "value": "user"
          }
        ]
      }
    ]
  }
}

И я бы хотел на месте изменить значение соответствующего ключа следующим образом:

jq '.taskDefinition.containerDefinitions[0].environment[] | select(.name=="DB_USERNAME") | .value="new"' json

Я получил вывод

{
  "name": "DB_USERNAME",
  "value": "new"
}

Но я хочу больше как изменение на месте или весь json из оригинала с измененным новым значением, например:

{
      "taskDefinition": {
        "containerDefinitions": [
          {
            "name": "web",
            "image": "my-image",
            "environment": [
              {
                "name": "DB_HOST",
                "value": "localhost"
              },
              {
                "name": "DB_USERNAME",
                "value": "new"
              }
            ]
          }
        ]
      }
    }

Возможно ли это сделать с jq или любым известным обходным путем?

Спасибо.

Обновлено

Для тех, кто ищет редактирование нескольких значений, вот подход, который я использую

JQ=""
for e in DB_HOST=rds DB_USERNAME=xxx; do
    k=${e%=*}
    v=${e##*=}
    JQ+="(.taskDefinition.containerDefinitions[0].environment[] | select(.name==\"$k\") | .value) |= \"$v\" | "
done

jq '${JQ%??}' json

Я думаю, что должен быть более лаконичный способ, но, похоже, он работает нормально.

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Возможно, вы захотите рассмотреть эту альтернативу использованию |=:

walk( if type=="object" and .name=="DB_USERNAME" 
      then .value="new" else . end)
0 голосов
/ 04 января 2019

Вот решение без выбора, использующее |=:

.taskDefinition.containerDefinitions[0].environment |=
  map(if .name=="DB_USERNAME" then .value = "new"
      else . end)

Исключение select в выражении на LHS |= делает решение более надежным w.r.t. используемая версия jq.

0 голосов
/ 04 января 2019

Достаточно назначить путь, если вы используете |=, например,

jq '
  (.taskDefinition.containerDefinitions[0].environment[] | 
   select(.name=="DB_USERNAME") | .value) |= "new"
' infile.json

Выход:

{
  "taskDefinition": {
    "containerDefinitions": [
      {
        "name": "web",
        "image": "my-image",
        "environment": [
          {
            "name": "DB_HOST",
            "value": "localhost"
          },
          {
            "name": "DB_USERNAME",
            "value": "new"
          }
        ]
      }
    ]
  }
}
...