добавление данных массива из файла в существующий массив с помощью jq

#arrays #json #merge #jq #insert-update

Вопрос:

Я создаю файл JSON (input.json), который выглядит следующим образом:

 [
  {
    "name": "MINIMUM_NOTICE_PERIOD",
    "value": "3"
  },
  {
    "name": "SERVER_TIMEZONE",
    "value": "Europe/London"
  }
]
 

У меня есть существующий файл JSON (task.json), который представляет собой определение задачи AWS ECS, которое выглядит следующим образом:

 {
  "family": "test-container",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "cpu": 0,
      "image": "test-image",
      "name": "test-container",
      "environment": [
          {
            "name": "CRON",
            "value": "no"
          },
          {
            "name": "LOG_CHANNEL",
            "value": "stack"
          }
        ]
    }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "512",
  "memory": "1024"
}

 

Я пытаюсь вставить дополнительные значения из файла JSON (input.json) в файл task def json (task.json)

Я использую команду:

 jq --argjson envVars "$(<input.json)" '.containerDefinitions[0].environment  = [$envVars]' task.json > new-task.json
 

Все шло хорошо до самого конца, когда результат:

 {
  "family": "test-container",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "cpu": 0,
      "image": "test-image",
      "name": "test-container",
      "environment": [
        {
          "name": "CRON",
          "value": "no"
        },
        {
          "name": "LOG_CHANNEL",
          "value": "stack"
        },
        [
          {
            "name": "MINIMUM_NOTICE_PE",
            "value": "3"
          },
          {
            "name": "SERVER_TIMEZONE",
            "value": "Europe/London"
          }
        ]
      ]
    },
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "512",
  "memory": "1024"
}
 

Это вставка полного содержимого файла, включая открытие и закрытие [], в существующий массив, я стремился к чему-то большему, чем это:

 {
  "family": "test-container",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "cpu": 0,
      "image": "test-image",
      "name": "test-container",
      "environment": [
        {
          "name": "CRON",
          "value": "no"
        },
        {
          "name": "LOG_CHANNEL",
          "value": "stack"
        },
        {
          "name": "MINIMUM_NOTICE_PE",
          "value": "3"
        },
        {
          "name": "SERVER_TIMEZONE",
          "value": "Europe/London"
        }
      ]
    },
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "512",
  "memory": "1024"
}
 

Я также попробовал команду:

 jq '.containerDefinitions[0].environment  = $inputs' task.json --slurpfile inputs input.json
 

Выполнение этого дает тот же результирующий вывод JSON.

Я попытался просто удалить скобки из файла inpur.json, но это приводит к следующей ошибке в обеих командах jq:

 jq: invalid JSON text passed to --argjson
 
 jq: Bad JSON in --slurpfile inputs input.json
 

У кого-нибудь есть идея, как получить результат, который я ищу? Любая помощь будет оказана, так как я выдергивал волосы, пытаясь разобраться в этой последней части.

Ответ №1:

input.json уже является массивом, поэтому ваш фильтр jq может быть таким же простым, как:

 .containerDefintions[0].environments  = $envVars
 

Использование —slurpfile приводит к переносу содержимого файла в массив, поэтому ваша вторая попытка должна быть связана $inputs[0] с этим .

Поскольку input.json это уже файл, я бы предложил использовать a --argfile (даже если он официально устарел); или, немного поработав, вы могли бы использовать вызов в соответствии с jq ... input.json task.json

Ответ №2:

В конце концов пик предложил правильный способ, используя $inputs[0] с —slurpfile, который сделал свое дело.