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

user2548436
  • 915
  • 2
  • 16
  • 35
  • `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`. – chepner Jul 20 '16 at 15:56

2 Answers2

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"}
chepner
  • 497,756
  • 71
  • 530
  • 681
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"}
Community
  • 1
  • 1
buff
  • 2,063
  • 10
  • 16