Sometimes you just want to read a JSON config file from Bash and iterate over an array. For example, when seeding some credentials to a credential store. This sometimes can be tricky especially when the JSON contains multi-line strings (for example certificates).

In this blog post I will explain how this can be done with jq and a Bash for loop.

First we will start with some data:

sample='[{"name":"foo"},{"name":"bar"}]'  
echo "${sample}" | jq '.'  
[
  {
    "name": "foo"
  },
  {
    "name": "bar"
  }
]

By using jq --compact-output (or -c) we can get each object on a newline.

sample='[{"name":"foo"},{"name":"bar"}]'  
echo "${sample}" | jq -c '.[]'  
{"name":"foo"}
{"name":"bar"}

We could start iterating of the above with a Bash for loop if our data does not contain spaces or newlines. But since certificates contain newlines we better base64 encode each line. Also, instead of -c, we now use -r to get rid of the extra quotes.

sample='[{"name":"foo"},{"name":"bar"}]'  
echo "${sample}" | jq -r '.[] | @base64'  
eyJuYW1lIjoiZm9vIn0=  
eyJuYW1lIjoiYmFyIn0=  

Now let's build our for loop.

sample='[{"name":"foo"},{"name":"bar"}]'  
for row in $(echo "${sample}" | jq -r '.[] | @base64'); do  
    _jq() {
     echo ${row} | base64 --decode | jq -r ${1}
    }

   echo $(_jq '.name')
done  
foo  
bar