Mensagem de erro “Não é possível indexar a matriz com a sequência 'Title'” ao analisar dados JSON com 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"
                }
                ]
            }
        ]
}
]
}

Eu tentei a abordagem abaixo, mas obtendo o erro

Não é possível indexar a matriz com a sequência "Título"

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

Eu estava tentando na mesma linha com outras seções, mas obtendo o mesmo erro.

Como resolvo esse problema?

Saída esperada:

abc,xyz,90,Normal.
abc,xyz,100,high.
abc,xyz,80,low
sam
fonte

Respostas:

12

Você não está recebendo Cannot index array with string "Title"esse comando, você está recebendo

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

como não há characteristicsou valuechave nos objetos da contentsmatriz (eles são chaves na .details.Temperaturesub-matriz).

O comando que lhe daria essa mensagem é:

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

ou

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

A falta da contentpesquisa de chave ou a falha na obtenção dos elementos da contentmatriz gera uma matriz de um objeto em vez do próprio objeto. E você não pode indexar uma matriz com uma string.


Supondo que você deseja saída 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"

O <object(s)> as <variable>age como um laço na jq, então o que acontece aqui é que $tserá atribuído a cada elemento .details.Temperature[], por sua vez, e para cada elemento, uma nova matriz é construída. A matriz é passada pela @csvqual produzirá linhas no formato CSV.

jqsempre aspas duplas nos campos de sua saída CSV. Para se livrar de citações desnecessárias :

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

( csvformatfaz parte de csvkit)

Ou, você pode usar @tsvno lugar de @csvpara obter saída delimitada por tabulação.

Kusalananda
fonte
2
Kusal Obrigado por suas contribuições. Estou usando a coisa acima com loop for. detalhes abaixo. para campo em certificações de temperatura; echo $ field :: jq --arg campo "$ field" -r '.content [] | .detalhes. "$ campo" [] como $ t | [Título, marca, valor de $ t, características de $ t] | @csv 'file.json concluído. mas obtendo "jq: error: try. [" field "] em vez de .field para campos com nomes incomuns em <top-level>, linha 1:"
sam
Eu entendi, não consegui correlacionar e estava colocando .details. $ [Field] ou .details. "$ Field". Agora mudei isso para .details [$ field] [] e está funcionando bem agora.
sam
1
@ sam Desculpe, eu estava em outro lugar. Sim, .details[$field][]ou .["details"][$field][]é a sintaxe correta.
Kusalananda
Eu votei e agradeço seu apoio.
sam
Kusal, desculpe por incomodá-lo novamente. É possível obter os principais valores do conteúdo sem fornecer o nome dos campos. "Título", "marca", "tamanho", "data". algo como jq -r .content [] | e me fornece todos os principais valores mencionados acima.
sam