简体   繁体   中英

Not able to get the desired output using jq

I have a json file like below: shopping-items.json

{
  "grocery" : [
    {
      "type": "fruits",
      "items" : [
        { "name": "mango", "quantity": "1kg" },
        { "name": "kiwi", "quantity": "2pc" },
        { "name": "apple", "quantity": "2kg" },
        { "name": "banana", "quantity": "6pc" }
      ]
    },
    {
      "type": "vegetables",
      "items" : [
        { "name": "potato", "quantity": "3kg" },
        { "name": "onion", "quantity": "2kg" },
        { "name": "tomato", "quantity": "2kg" }
      ]
    },
    {
      "type": "dryfruits",
      "items" : [
        { "name": "almonds", "quantity": "2kg" },
        { "name": "cachewnut", "quantity": "1kg" },
        { "name": "walnut", "quantity": "1.5kg" }
      ]
    },
    {
      "type": "pulses",
      "items" : [
        { "name": "Blackgram", "quantity": "1kg" },
        { "name": "chickpeas", "quantity": "2kg" },
        { "name": "lentils", "quantity": "1.5kg" }
      ]
    }
  ]
}

I have tried several jq queries on this set:-

$ cat shopping-items.json | jq -r '.grocery[] | .items[] | [.name, .quantity]  | join (",")'
mango,1kg
kiwi,2pc
apple,2kg
banana,6pc
potato,3kg
onion,2kg
tomato,2kg
almonds,2kg
cachewnut,1kg
walnut,1.5kg
Blackgram,1kg
chickpeas,2kg
lentils,1.5kg
$ cat shopping-items.json | jq -r '.grocery[] | [.type, .items[].name, .items[].quantity] | join (",")'
fruits,mango,kiwi,apple,banana,1kg,2pc,2kg,6pc
vegetables,potato,onion,tomato,3kg,2kg,2kg
dryfruits,almonds,cachewnut,walnut,2kg,1kg,1.5kg
pulses,Blackgram,chickpeas,lentils,1kg,2kg,1.5kg

But desired result is as below:-

fruits,mango,1kg
fruits,kiwi,2pc
fruits,apple,2kg
fruits,banana,6pc
vegetables,potato,3kg
vegetables,onion,2kg
vegetables,tomato,2kg
dryfruits,almonds,2kg
dryfruits,cachewnut,1kg
dryfruits,walnut,1.5kg
pulses,Blackgram,1kg
pulses,chickpeas,2kg
pulses,lentils,1.5kg

There is a way, but I feel it's not efficient. Looking for an efficient way for this result.

filename=shopping-items.json
count=`cat ${filename} | jq -c '.grocery[] | keys' | wc -l`
counter=0
while [ $counter -lt $count ]
do
  var_type=`cat ${filename} | jq -r .grocery[$counter].type`
  jq --arg var_type $var_type --argjson c $counter --raw-output '.grocery[$c].items[] | [$var_type, .name, .quantity] | join(",")' ${filename}
  counter=`expr $counter + 1`
done

To achieve the desired result, you can simply invoke jq once using thie following jq program:

.grocery[]
| [.type] + ( .items[] | [.name, .quantity])
| join (",")

See it in action at jqplay.org

jqplay.org

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM