Json Object Parsing using shell script

Viewed 89

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

2 Answers

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

Add a loop to iterate each city in $city_array for each $countryObj, then echo your desired output line-by-line.

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");
    
    for city in $city_array; do
        echo "country:$countryValue, city:$city"
    done

    echo "" # Blank line between each country
done
Related