2014-11-03 185 views
9

我有一个Bash脚本。它使用JSON获取数据。 我需要将JSON数组转换为Bash数组。将JSON数组转换为Bash数组

{ 
    "SALUTATION": "Hello world", 
    "SOMETHING": "bla bla bla Mr. Freeman" 
} 

在bash我想这样echo ${arr[SOMETHING]}值。

+0

我试着用'JQ -r” .param_name'' 但它的工作,只有当我们知道参数的名称 – Evgenii 2014-11-03 15:25:47

+1

如果你的脚本收到任意的JSON,这可能不可能在纯粹的bash中完成。 – helpermethod 2014-11-03 15:27:05

回答

15

如果你想键和值,并根据How do i convert a json object to key=value format in JQ,你可以这样做:

$ jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" file 
SALUTATION=Hello world 
SOMETHING=bla bla bla Mr. Freeman 

在更普遍的方式,你可以将值存储到一个数组myarray[key] = value这个样子,只是通过提供jq到该whilewhile ... do; ... done < <(command)语法:

declare -A myarray 
while IFS="=" read -r key value 
do 
    myarray[$key]="$value" 
done < <(jq -r "to_entries|map(\"\(.key)=\(.value)\")|.[]" file) 

然后你可以通过这样的价值观循环:

for key in "${!myarray[@]}" 
do 
    echo "$key = ${myarray[$key]}" 
done 

对于这个给定的输入,则返回:

SALUTATION = Hello world 
SOMETHING = bla bla bla Mr. Freeman 
+1

它只是将根元素添加到数组中。它不是递归的。 – PhoenixNoor 2016-02-20 23:00:01

+0

@PhoenixNoor,请看我的回答递归方式:https://stackoverflow.com/a/47026579/720323 – HelpNeeder 2017-10-31 01:24:18

4

的OP的问题实际上描述对象,数组VS。

为了确保我们帮助其他人进来,他们实际上是寻找JSON数组的帮助,但是,这是值得明确的覆盖他们。


为了安全上下的情况下字符串不能包含换行符(和当bash 4.0或更高版本在使用),这个工程:

str='["Hello world", "bla bla bla Mr. Freeman"]' 
readarray -t array <<<"$(jq -r '.[]' <<<"$str")" 

为了支持老版本的bash,和与换行符的字符串,我们得到了一个有点票友,使用NUL分隔流从jq阅读:

str='["Hello world", "bla bla bla Mr. Freeman", "this is\ntwo lines"]' 
array=() 
while IFS= read -r -d '' line; do 
    array+=("$line") 
done < <(jq -j '.[] | (. + "\u0000")') 
1

这是怎么能够完成递归:

#!/bin/bash 

SOURCE="$PWD" 
SETTINGS_FILE="$SOURCE/settings.json" 
SETTINGS_JSON=`cat "$SETTINGS_FILE"` 

declare -A SETTINGS 

function get_settings() { 
    local PARAMS="$#" 
    local JSON=`jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" <<< "$1"` 
    local KEYS='' 

    if [ $# -gt 1 ]; then 
     KEYS="$2" 
    fi 

    while read -r PAIR; do 
     local KEY='' 

     if [ -z "$PAIR" ]; then 
      break 
     fi 

     IFS== read PAIR_KEY PAIR_VALUE <<< "$PAIR" 

     if [ -z "$KEYS" ]; then 
      KEY="$PAIR_KEY" 
     else 
      KEY="$KEYS:$PAIR_KEY" 
     fi 

     if jq -e . >/dev/null 2>&1 <<< "$PAIR_VALUE"; then 
      get_settings "$PAIR_VALUE" "$KEY" 
     else 
      SETTINGS["$KEY"]="$PAIR_VALUE" 
     fi 
    done <<< "$JSON" 
} 

要叫它:

get_settings "$SETTINGS_JSON" 

的阵列将像这样来访问:

${SETTINGS[grandparent:parent:child]}