Bashjq解析json字符串
Bash Jq parse json string
我必须调用一个文件并以这种方式传递一个 json 作为参数
(假设我的文件名为 test.sh),从 bash 我需要做这样的事情:
./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=""
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 "$accounts" 的输出是这样的
[
[
{
"username":
"user1"
等等等等。每个令牌一个对象:-(
等等,但我期待的是一个包含三个对象的数组(就像您可以在 jqplay.org 上测试)
{
"username": "user1",
"password": "pwd1",
"group": "usergroup1"
}
{
"username": "user2",
"password": "pwd2",
"group": "usergroup2"
}
{
"username": "user3",
"password": "pwd3",
"group": "usergroup3"
}
通过这种方式,我可以在 ${accounts[@]}
上创建一个 foreach
我做错了什么?
谢谢
您正在交换 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
(从这里偷来的:)
得到以下输出:
{"username":"user1","password":"pwd1","group":"usergroup1"}
{"username":"user2","password":"pwd2","group":"usergroup2"}
{"username":"user3","password":"pwd3","group":"usergroup3"}
使用 -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"}
我必须调用一个文件并以这种方式传递一个 json 作为参数 (假设我的文件名为 test.sh),从 bash 我需要做这样的事情:
./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=""
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 "$accounts" 的输出是这样的
[
[
{
"username":
"user1"
等等等等。每个令牌一个对象:-(
等等,但我期待的是一个包含三个对象的数组(就像您可以在 jqplay.org 上测试)
{
"username": "user1",
"password": "pwd1",
"group": "usergroup1"
}
{
"username": "user2",
"password": "pwd2",
"group": "usergroup2"
}
{
"username": "user3",
"password": "pwd3",
"group": "usergroup3"
}
通过这种方式,我可以在 ${accounts[@]}
上创建一个 foreach我做错了什么? 谢谢
您正在交换 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
(从这里偷来的:)
得到以下输出:
{"username":"user1","password":"pwd1","group":"usergroup1"}
{"username":"user2","password":"pwd2","group":"usergroup2"}
{"username":"user3","password":"pwd3","group":"usergroup3"}
使用 -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"}