Search code examples
arraysjsonbashshelljq

Json Object Parsing using shell script


I am trying to parse below json object using shell script:

country.json

 {
        "countries": [
            {"country":"India","city":["India1","India2","India3"]},
            {"country":"USA","city":["USA1","USA2","USA3"]}
           
           ]
    }

and my desired output should be like:

country:India, city:India1
country:India, city:India2
country:India, city:India3

country:USA, city:USA1
country:USA, city:USA2
country:USA, city:USA3 

I am using jq in shell script to iterate the above json like this:

for k in $(jq '.countries | keys | .[]' country.json); do
    countryObj=$(jq -r ".countries[$k]" country.json);
    countryValue=$(jq -r '.country' <<< "$countryObj");
    city_array=$(jq -r '.city' <<< "$countryObj");
    echo $city_array
done 

from this I am able to get city_array i.e. ["India1","India2","India3"] and ["USA1","USA2","USA3"] but I am not able to get desired output mentioned above


Solution

  • This can be done entirely in jq.

    jq -r '
       .countries |
       map(
          .country as $country |
          .city | map("country: \( $country ), city: \( . )\n") | add
       ) |
       join("\n")
    '
    

    Gives:

    country: India, city: India1
    country: India, city: India2
    country: India, city: India3
    
    country: USA, city: USA1
    country: USA, city: USA2
    country: USA, city: USA3
    

    jqplay


    If you don't need that blank line, it's a lot simpler.

    jq -r '
       .countries[] |
       .country as $country |
       .city[] |
       "country: \( $country ), city: \( . )"
    '
    

    jqplay


    With a tip from Oliver Sinclair InfoSleuth, the later can be reduced to

    jq -r '.countries[] | "country: \( .country ), city: \( .city[] )"'
    

    jqplay