2016-07-20 4 views
1

Я вызвать файл и передать JSON в качестве параметров таким образом (предположу, что мой файл называется test.sh), от Баша мне нужно сделать что-то вроде этого:Bash Jq разбор JSON строка

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

и содержание test.sh следующая

#!/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 

выход -> PRINTF "$ SYSTEM_USER" является

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

но выход -> PRINTF «$ счета» это что-то вроде этого

[
[
{
«имя пользователя»:
«user1»
и т.д. и т.п. один объект для каждого маркера: - (

и так далее, но то, что я ожидал, что это массив из трех объектов (например, вы можете проверить на jqplay.org)

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

Таким образом, я могу сделать foreach на $ {accounts [@]}

Что я делаю неправильно? Спасибо

+0

'jq '. []' <<<" ... "' (без '-s') дает желаемый результат; вы можете подумать о том, почему вы считаете, что вам нужен массив 'bash', чтобы держать это в первую очередь. В зависимости от того, что вы хотите * делать * с данными, вы можете сделать это прямо в 'jq'. – chepner

ответ

2

С опцией -c, вы можете распечатать каждый объект JSON на одна строка, что упрощает заполнение массива, который вы хотите.

$ 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"} 
+0

-c вариант - это путь, спасибо – user2548436

1

Вы переставляете массивы bash и массивы JSON. Когда вы создаете массив accounts, bash разбивает элементы на каждое пробельное пространство. Вот почему вы не получаете то, что ожидаете. Вы можете попробовать следующее:

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 

(украдено отсюда: https://stackoverflow.com/a/26717401/328977)

, чтобы получить следующий вывод:

{"username":"user1","password":"pwd1","group":"usergroup1"} 
{"username":"user2","password":"pwd2","group":"usergroup2"} 
{"username":"user3","password":"pwd3","group":"usergroup3"} 
Смежные вопросы