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

#json #jq

#json #jq

Вопрос:

У меня есть ввод, подобный этому:

 "data": [{
        "id": 111585,
        "name": "Inverter",
        "batList": [{
            "name": "Battery1",
            "dataDict": [{
                "key": "b1_1",
                "name": "Battery V.",
                "value": 57.63,
                "unit": "V"
            }, {
                "key": "b1_2",
                "name": "Battery I.",
                "value": -0.10,
                "unit": "A"
            }, {
                "key": "b1_3",
                "name": "Battery P.",
                "value": -6,
                "unit": "W"
            }, {
                "key": "b1_4",
                "name": "Inner T.",
                "value": 25,
                "unit": "℃"
            }, {
                "key": "b1_5",
                "name": "Remaining Capacity % ",
                "value": 99,
                "unit": "%"
            }]
        }]
    }],
  

из которого я хочу извлечь свойство ‘value’ (т. е. 99) для «Оставшейся емкости%».

Моя лучшая любительская, но хорошо проверенная попытка

 jq --arg instance "Remaining Capacity % " '.data | .[] | select(.name == $instance) | .value')
  

но я получаю пустой результат. Любая помощь с этой вложенной непримиримостью была бы высоко оценена.

Ответ №1:

Ваша идея кажется правильной, но вы пропустили упоминание путей верхнего уровня после .data[] , это должно было быть

 jq --arg instance "Remaining Capacity % " 
     '.data[].batList[].dataDict[] | select(.name == $instance ).value' json
  

Комментарии:

1. Работает! Я, должно быть, перепробовал все комбинации вокруг вашего решения, ожидая правильного. Я получал jq: ошибка Не удается проиндексировать массив с помощью string большую часть времени, когда я пробовал batList [] и т.д.. Спасибо за вашу оперативную помощь.

Ответ №2:

Альтернативой ответу Иниана является использование рецепта select-contains, например:

 jq -r '.[].batList[].dataDict[] | select(.name|contains("Remaining")).value' file
  

Хотя в этом примере ничего лучшего нет, его удобно запомнить, особенно если вам нужно найти кучу значений, например, contains("Battery") вернет три результата.