1

I've to call a file and pass a json as parameters in this way (suppose that my file is called test.sh), from bash I need to do something like this:

./test.sh "[{\"username\":\"user1\",\"password\":\"pwd1\",\"group\":\"usergroup1\"},{\"username\":\"user2\",\"password\":\"pwd2\",\"group\":\"usergroup2\"},{\"username\":\"user3\",\"password\":\"pwd3\",\"group\":\"usergroup3\"}]"

and the content of test.sh is the following

#!/bin/bash

#read the json
system_user="$1"

printf "$system_user"

accounts=($(jq -s ".[]" <<< $system_user))

printf "$accounts"

for account in "${accounts[@]}"
do
  printf "\n\n$account\n\n"
done 

the output of -> printf "$system_user" is

[{"username":"user1","password":"pwd1","group":"usergroup1"},{"username":"user2","password":"pwd2","group":"usergroup2"},{"username":"user3","password":"pwd3","group":"usergroup3"}]

but the output of -> printf "$accounts" is something like this

[
[
{
"username":
"user1"
etc. etc. one object for each token :-(

and so on, but what I was expecting is an array of three object (like you can test on jqplay.org)

 {
   "username": "user1",
   "password": "pwd1",
   "group": "usergroup1"
 }
 {
   "username": "user2",
   "password": "pwd2",
   "group": "usergroup2"
 }
 {
   "username": "user3",
   "password": "pwd3",
   "group": "usergroup3"
 }

In this way I can make a foreach on ${accounts[@]}

What I'm doing wrong? Thank you

1
  • jq '.[]' <<< "..." (without the -s) gives you the output you want; you might want to consider why you think you need a bash array to hold that in the first place. Depending on what you want to do with the data, you may be able to do it directly in jq. Commented Jul 20, 2016 at 15:56

2 Answers 2

2

With the -c option, you can print each JSON object on a single line, making it easier to populate the array you want.

$ readarray -t arr < <(jq -c '.[]' <<< "[{\"username\":\"user1\",\"password\":\"pwd1\",\"group\":\"usergroup1\"},{\"username\":\"user2\",\"password\":\"pwd2\",\"group\":\"usergroup2\"},{\"username\":\"user3\",\"password\":\"pwd3\",\"group\":\"usergroup3\"}]") 
$ printf "Object: %s\n" "${arr[@]}"
Object: {"username":"user1","password":"pwd1","group":"usergroup1"}
Object: {"username":"user2","password":"pwd2","group":"usergroup2"}
Object: {"username":"user3","password":"pwd3","group":"usergroup3"}
Sign up to request clarification or add additional context in comments.

Comments

1

You are interchanging bash arrays and JSON arrays. When you are creating accounts array, bash splits the elements per each whitespace. That's why you don't get what you expect. You can try the following:

declare -A accounts

while IFS="=" read -r key value
do
    accounts[$key]="$value"
done < <(jq -r "to_entries|map(\"\(.key)=\(.value)\")|.[]" <<< $system_user)

for account in "${accounts[@]}"
do
    printf "$account\n"
done

(stolen from here: https://stackoverflow.com/a/26717401/328977)

to get the following output:

{"username":"user1","password":"pwd1","group":"usergroup1"}
{"username":"user2","password":"pwd2","group":"usergroup2"}
{"username":"user3","password":"pwd3","group":"usergroup3"}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.