[jq] Transforming a JSON Object into an Associative Bash Array using jq

By | January 18, 2018

JSON is everywhere and playing with API outputs from the command line is getting much more easier since we have jq, the “lightweight and flexible command-line JSON processor”

Here is a small snipet I use to transform some simple JSON into an associative bash array

Lets pretend that we have an api at http://example.com/myapi returning the following output

[
  {
    "service": "one",
    "endpoint": "example.com/service1",
    "timeout": 1,
    "status": "up"
  },
  {
    "service": "two",
    "endpoint": "example.com/service2",
    "timeout": 2,  
    "status": "down"
  },
  {
    "service": "three",
    "endpoint": "example.com/service3",
    "timeout": 3,
    "status": "up"
  }
]

Imagine now that we need to expose this information to some program, we could do something like that :

URL="http://example.com/myapi"

declare -A assoc_array="($(
  curl -sS "${URL}" \
  | jq '.[]  | "[" + .service + "]=\"" +.endpoint + "\""' -r
))"

We now have a populated ${assoc_array} bash array that we can walk like this

for i in ${!assoc_array[@]}; do echo $i ${assoc_array[$i]}; done

Using jq we could even filter out the services that  are “down”

declare -A assoc_array="($(
  curl -sS "${URL}" \
  | jq '.[] | select(.status == "up") | "[" + .service + "]=\"" +.endpoint + "\""' -r
))"

Imagine now that we need to export as many environment variables as services present in the API output; We could do :

URL="http://example.com/myapi"

declare -A assoc_array="($(
  curl -sS "${URL}" \
  | jq '.[]  | "[" + .service + "]=\"" +.endpoint + "\""' -r
))"

for key in ${!assoc_array[@]}; do 
  sanitizedKey=${key/-/_};
  eval ZBO_${sanitizedKey^^}='$(echo ${assoc_array[$key]})';
done
Сomments аrchive