2014-11-03 275 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]}