13
{
    "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"
                }
                ]
            }
        ]
}
]
}

I have tried the below approach, but getting the error

Cannot index array with string "Title"

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

I was trying on the same line with other sections, but getting the same error.

How do I solve this issue?

Expected output:

abc,xyz,90,Normal.
abc,xyz,100,high.
abc,xyz,80,low
sam
  • 171

1 Answers1

15

You are not getting Cannot index array with string "Title" with that command, you are getting

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

since there is no characteristics or value key in the objects of the contents array (they are keys in the .details.Temperature sub-array).

The command that would have given you that message is:

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

or

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

Missing out the content key lookup, or failing to get the elements of the content array, yields an array of one object rather than the object itself. And you can't index an array with a string.


Assuming you want CSV output:

$ 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"

The <object(s)> as <variable> acts like a loop in jq, so what happens here is that $t will be assigned each element of .details.Temperature[] in turn, and for each element, a new array is constructed. The array is passed through @csv which will output CSV-formatted rows.

jq will always double quote the fields of its CSV output. To get rid of unnecessary quotes:

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

(csvformat is part of csvkit)

Or, you may want to use @tsv in place of @csv to get tab-delimited output instead.

Kusalananda
  • 333,661
  • 2
    Kusal Thank you for your inputs. I am using above thing with for loop. details below. for field in Temperature certifications ; do echo $field :: jq --arg field "$field" -r ' .content[] | .details."$field"[] as $t | [.Title,.brand,$t.value,$t.characteristics] | @csv' file.json done. but getting "jq: error: try .["field"] instead of .field for unusually named fields at , line 1:" – sam Mar 17 '19 at 10:49
  • I got this, I was not able to correlate and was putting .details.$[field] or .details."$field". Now I have changed that to .details[$field][] and it's working fine now. – sam Mar 17 '19 at 12:12
  • 1
    @sam Sorry, I was elsewhere. Yes, .details[$field][] or .["details"][$field][] is the correct syntax. – Kusalananda Mar 17 '19 at 12:23
  • I have up-voted and thank you for your support. – sam Mar 17 '19 at 18:05
  • Kusal,sorry for bothering you again. Is it possible to get the content main values without giving the name of fields."Title","brand","size","date" values. something like jq -r .content[] | and it give me all the main values as mentioned above. – sam Mar 19 '19 at 06:11