I want to convert the following JSON content stored in a file tmp.json
{
"results": [
[
{
"field": "field1",
"value": "value1-1"
},
{
"field": "field2",
"value": "value1-2"
},
{
"field": "field3",
"value": "value1-3"
}
],
[
{
"field": "field1",
"value": "value2-1"
},
{
"field": "field2",
"value": "value2-2"
},
{
"field": "field3",
"value": "value2-3"
}
],
[
{
"field": "field1",
"value": "value3-1"
},
{
"field": "field2",
"value": "value3-2"
},
{
"field": "field3",
"value": "value3-3"
}
]
]
}
into CSV output:
"field1","field2"
"value1-1","value1-2"
"value2-1","value2-2"
"value3-1","value3-2"
The closest jq expression I've come up with is this:
cat ./tmp.json | jq -r '.results | [ .[] | del(last) ] | (first | map(.field)), (.[] | map(.value)) | @csv'
It works for jq version 1.6, but for version 1.5, the last "column" is still included in the CSV result. How do I edit the jq code so that it works for version 1.5?
Note that the number of columns is not limited to 3; it can be more. The jq code should be able to remove the last column in the final CSV result.
CodePudding user response:
You can use the slice operator to extract the sub-elements of the array inside each field and put into an array and use the @csv
[ .results[][:-1] ] | (first | map(.field)), (.[] | map(.value)) | @csv
The part .results[][:-1]
extracts all the elements except the last one in the array. From the manual
Either index may be negative (in which case it counts backwards from the end of the array), or omitted (in which case it refers to the start or end of the array).
See jqplay for a working demo.
I was able to reproduce the bug in jq-1.5. Its a known fact that there are major bugs fixed as part of release 1.6 in del/1. So consider upgrading to use del/1 or use the slice expression as indicated in the answer above