【问题标题】:Bash Jq parse json stringBash Jq解析json字符串
【发布时间】:2016-07-20 14:47:03
【问题描述】:

我必须以这种方式调用一个文件并传递一个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="$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 "$accounts" 的输出是这样的

[
[
{
“用户名”:
“用户1”
等等等等,每个令牌都有一个对象 :-(

等等,但我期待的是一个包含三个对象的数组(就像你可以在 jqplay.org 上测试一样)

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

通过这种方式,我可以在 ${accounts[@]}

上创建一个 foreach

我做错了什么? 谢谢

【问题讨论】:

  • jq '.[]' &lt;&lt;&lt; "..."(没有-s)给你你想要的输出;您可能要考虑为什么您认为首先需要一个 bash 数组来保存它。根据您想对数据做什么,您可以直接在jq 中执行。

标签: json linux bash ubuntu jq


【解决方案1】:

使用-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"}

【讨论】:

    【解决方案2】:

    您正在交换 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"}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多