Сообщение об ошибке «Невозможно индексировать массив строкой« Заголовок »» при анализе данных JSON с помощью jq.

9
{
    "content": [
    {
        "Title": "abc",
        "brand": "xyz",
        "size": "5 g",
        "date": "2019-01-01",
        "details": {
            "Temperature": [
            {
                "value": "90",
                "characteristics":"Normal"
            },
            {
                "value":"100",
                "characteristics":"high"
            },

            {
                "value":"80",
                "characteristics":"low"
            }
            ],

            "certifications": [
            {
                "value": "based",
                "characteristics":"pass"
            },

            {
                "value": "50",
                "characteristics":"failed"
            }
            ]
        },

         "formats": {
            "city": "NYC",
            "id": "007",
            "manufacture":""
            },
        "innerDetails": [
        {
            "contains": "abc",
            "panel":"xyz",
            "values":[
                {
                    "name":"abc",
                    "value":"10"
                },
                {
                    "name":"xyz",
                    "value":"20"
                }
                ]
            }
        ]
}
]
}

Я попробовал следующий подход, но получаю ошибку

Невозможно индексировать массив строкой «Заголовок»

jq -r '.content[]|[.Title,.brand,.characteristics,.value]' $jsonfile.

Я пытался в той же строке с другими разделами, но получаю ту же ошибку.

Как мне решить эту проблему?

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

abc,xyz,90,Normal.
abc,xyz,100,high.
abc,xyz,80,low
Сэм
источник

Ответы:

12

Вы не получаете Cannot index array with string "Title"с этой командой, вы получаете

[
  "abc",
  "xyz",
  null,
  null
]

поскольку в объектах массива нет characteristicsни valueключа, ни ключа contents(они являются ключами в .details.Temperatureподмассиве).

Команда, которая дала бы вам это сообщение:

jq -r '.[] | [.Title,.brand,.characteristics,.value]' "$jsonfile"

или

jq -r '.content | [.Title,.brand,.characteristics,.value]' "$jsonfile"

Если пропустить contentпоиск ключей или получить элементы contentмассива, получается массив из одного объекта, а не сам объект. И вы не можете индексировать массив строкой.


Предполагая, что вы хотите вывод CSV:

$ jq -r '.content[] | .details.Temperature[] as $t | [.Title,.brand,$t.value,$t.characteristics] | @csv' file.json
"abc","xyz","90","Normal"
"abc","xyz","100","high"
"abc","xyz","80","low"

<object(s)> as <variable>Действует как цикл в jq, так что здесь происходит то , что $tбудет назначен каждый элемент , .details.Temperature[]в свою очередь, и для каждого элемента, новый массив строится. Передается массив, через @csvкоторый будут выводиться строки в формате CSV.

jqвсегда будет дважды заключать в кавычки поля своего вывода CSV. Чтобы избавиться от ненужных цитат:

jq -r '...as above...' file.json | csvformat

( csvformatявляется частью csvkit)

Или, вы можете использовать @tsvвместо, @csvчтобы получить вывод с разделителями табуляции вместо этого.

Кусалананда
источник
2
Кусал Спасибо за ваш вклад. Я использую вышеуказанную вещь с для цикла. подробности ниже. для поля в сертификации температуры; do echo $ field :: jq --arg field "$ field" -r '.content [] | .details. "$ field" [] as $ t | [.Title, .brand, $ t.value, $ t.characteristics] | @csv 'file.json сделано. но получая "jq: error: try. [" field "] вместо .field для полей с необычным именем в <top-level>, строка 1:"
Сэм
Я получил это, я не смог сопоставить и помещал .details. $ [Field] или .details. "$ Field". Теперь я изменил это на .details [$ field] [], и теперь он работает нормально.
сэм
1
@ sam Извините, я был в другом месте. Да, .details[$field][]или .["details"][$field][]это правильный синтаксис.
Кусалананда
Я проголосовал за и спасибо за вашу поддержку.
Сэм
Кусал, извините за беспокойство снова. Можно ли получить содержимое основных значений без указания названия полей. Значения «Название», «Бренд», «Размер», «Дата». что-то вроде jq -r .content [] | и это дает мне все основные ценности, как указано выше.
Сэм