Tuesday, October 4, 2022

[SOLVED] Extract values from JSON objects and assign them to shell variables in a loop

Issue

I am using jq like below to parse a json file -

The json file looks something like -

{
  "values": [
    {
      "email": "[email protected]",
      "id": "USER1_ID"
    },{
      "email": "[email protected]",
      "id": "USER2_ID"
    },
    .
]
}

I am able to print/ iterate through the ids like below

for k in $(cat input.json | jq .values | jq .[].id); do
    echo $k
done

This prints each individual id as expected.

However, what I want is to access both the email and the id in the loop.

I tried to assign values to SHELL variables like below -

emails=$(cat input.json | jq .values | jq .[].email)
ids=$(cat input.json | jq .values | jq .[].id)

This could work for the most part but ids can have spaces too which is breaking this.

I could essentially have to 2 for loops one for email and the other for id and assign values to arrays in the loop

   i=0
    for k in $(cat input.json | jq .values | jq .[].id); do
            ids[$i]=$k
            i=$(($i +1)) 
        done

and

i=0
for k in $(cat input.json | jq .values | jq .[].email); do
        emails[$i]=$k
        i=$(($i +1)) 
    done

Once I have both the values in arrays, I could parallely traverse both of them.

I am not a shell expert so I wanted to know if there is any slick way of doing this with fewer loops/ lines of code.

Thanks for any help!


Solution

You can output each email-ID pair as a comma separated list from JQ, and use read them into variables in a while loop like so:

while IFS=',' read -r email id; do
  echo "$email"
  echo "$id"
done <<EOF
$(jq -r '.values[] | "\(.email),\(.id)"' file)
EOF


Answered By - oguz ismail
Answer Checked By - Cary Denson (WPSolving Admin)