jq выбирает несколько элементов из массива

Вопрос или проблема

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

{
  "type": "server-firmwareinventory-list-1",
  "members": [
    {
      "type": "sever-hardware-firmware-1",
      "category": "sever-hardware",
      "serverName": "my-host",
      "components": [
        {
          "componentName": "firmware-hdd-8051bb7e9c",
          "componentDescription": "Прошивка дисков VS000480KXALB, VS003840KWXFQ, VS001920KWXFP и VS000960KWXFN",
          "componentVersion": "85032G00-4.1"
        },
        {
          "componentName": "Системный ROM",
          "componentDescription": "SystemRomActive",
          "componentVersion": "A46 v2.80 (07/31/2023)"
        },
        {
          "componentName": "Резервный системный ROM",
          "componentDescription": "SystemRomBackup",
          "componentVersion": "A46 v2.60 (08/11/20223)"
        }
      ],
    "serverFirmwareSettings": null
    }
  ]
}

Я могу успешно получить активный системный ROM для каждого сервера с помощью (${FIRMW} указывает на файл, содержащий JSON).

jq -r '.members[] | {"serverName": .serverName, "system-firmware": .components[] | select(.componentName=="System ROM") | .componentVersion }' ${FIRMW}

Я хотел добавить резервный системный ROM, поэтому я попробовал:

jq -r '.members[] | {"serverName": .serverName, "system-firmware": .components[] | select(.componentName=="System ROM") | .componentVersion, "system-firmware-backup": | select(.componentName=="Redundant System ROM") | .componentVersion }' ${FIRMW}

но это выдает мне ошибку синтаксиса, неожиданное ‘|’ на первой строке. Есть идеи, как это исправить?

Вы забыли отфильтровать массив compontents при выборе Redundant System ROM.

Исправленный вариант вашего кода с добавлением некоторых сокращений (обратите внимание, что -r не нужен, так как вы выводите JSON, а не сырые строки):

jq '.members[] |
    {
        serverName,
        "system-firmware":
            .components[] | select(.componentName == "System ROM").componentVersion,
        "system-firmware-backup":
            .components[] | select(.componentName == "Redundant System ROM").componentVersion
    }' file

С учетом данных в вопросе, это даст вам следующий JSON-документ:

{
  "serverName": "my-host",
  "system-firmware": "A46 v2.80 (07/31/2023)",
  "system-firmware-backup": "A46 v2.60 (08/11/20223)"
}

Ответ или решение

Как выбрать несколько элементов из массива с помощью jq

В современных системах управления конфигурациями и мониторинга оборудования часто возникает необходимость извлекать информация из JSON-структур. В рамках этой статьи мы рассмотрим, как использовать утилиту jq для извлечения нескольких элементов из массива JSON, основываясь на предоставленном примере.

Пример структуры JSON

Для начала, рассмотрим данную JSON-структуру, содержащую информацию о сервере и его компонентах:

{
  "type": "server-firmwareinventory-list-1",
  "members": [
    {
      "type": "sever-hardware-firmware-1",
      "category": "sever-hardware",
      "serverName": "my-host",
      "components": [
        {
          "componentName": "firmware-hdd-8051bb7e9c",
          "componentDescription": "VS000480KXALB, VS003840KWXFQ, VS001920KWXFP, and VS000960KWXFN Drives firmware",
          "componentVersion": "85032G00-4.1"
        },
        {
          "componentName": "System ROM",
          "componentDescription": "SystemRomActive",
          "componentVersion": "A46 v2.80 (07/31/2023)"
        },
        {
          "componentName": "Redundant System ROM",
          "componentDescription": "SystemRomBackup",
          "componentVersion": "A46 v2.60 (08/11/20223)"
        }
      ],
      "serverFirmwareSettings": null
    }
  ]
}

Цель

Наша задача заключается в извлечении двух параметров версий прошивки: активной прошивки (System ROM) и резервной прошивки (Redundant System ROM) для каждого сервера.

Изначальная попытка

Вы уже успешно извлекали активную прошивку с помощью следующей команды:

jq -r '.members[] | {"serverName": .serverName, "system-firmware": .components[] | select(.componentName == "System ROM") | .componentVersion }' ${FIRMW}

Однако вы столкнулись с синтаксической ошибкой при попытке дополнить команду для извлечения резервной прошивки:

jq -r '.members[] | {"serverName": .serverName, "system-firmware": .components[] | select(.componentName == "System ROM") | .componentVersion, "system-firmware-backup": | select(.componentName == "Redundant System ROM") | .componentVersion }' ${FIRMW}

Поправленный вариант команды

Ошибки связаны с тем, что в последнем выражении вы забыли отфильтровать массив components для резервной прошивки. Кроме того, использование флага -r излишне, так как мы выводим JSON, а не сырой текст. Вот исправленный вариант команды:

jq '.members[] | {
    serverName,
    "system-firmware": .components[] | select(.componentName == "System ROM").componentVersion,
    "system-firmware-backup": .components[] | select(.componentName == "Redundant System ROM").componentVersion
}' ${FIRMW}

Ожидаемый результат

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

{
  "serverName": "my-host",
  "system-firmware": "A46 v2.80 (07/31/2023)",
  "system-firmware-backup": "A46 v2.60 (08/11/20223)"
}

Заключение

Использование утилиты jq для работы с JSON данными позволяет гибко и эффективно извлекать нужную информацию. В данном примере мы рассмотрели, как выбрать несколько компонентов из массива и избежать синтаксических ошибок при работе с фильтрами. Эти навыки помогут вам в управлении конфигурациями и мониторинге аппаратуры с использованием стандартных инструментов командной строки.

Теперь вы обладаете необходимыми знаниями для эффективного извлечения данных из JSON, что улучшает работу с системами управления и поддержкой серверов.

Оцените материал
Добавить комментарий

Капча загружается...