2014-11-03 5 views
9

Ich habe ein Bash-Skript. Es erhält Daten in JSON. Ich muss das JSON-Array in ein Bash-Array konvertieren.Konvertieren eines JSON-Arrays in ein Bash-Array

Beispiel

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

In Bash Ich möchte ähnliche echo ${arr[SOMETHING]} einen Wert erhalten.

+0

ich versuchen 'jq -r‘ .param_name'' aber seine Arbeit nur, wenn wir Name des Parameters kennen – Evgenii

+1

Wenn Ihr Skript eine beliebige JSON empfängt, ist dies in pure bash nicht möglich. – helpermethod

Antwort

15

Wenn Sie Schlüssel und Wert gewünscht wird, und basierend auf How do i convert a json object to key=value format in JQ, können Sie tun:

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

In einer allgemeineren Art und Weise, können Sie die Werte in ein Array myarray[key] = value wie diese speichern kann, nur indem jq zu die while mit der while ... do; ... done < <(command) Syntax:

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

und dann können Sie eine Schleife durch die Werte wie folgt aus:

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

Für diesen gegebenen Eingang, gibt sie:

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

Es dauerte nur das Wurzelelement und fügte es dem Array hinzu. Es ist nicht rekursiv. – PhoenixNoor

+0

@PhoenixNoor, bitte schauen Sie sich meine rekursive Antwort an: https://Stackoverflow.com/a/47026579/720323 – HelpNeeder

4

Die Frage des OP-Objekte tatsächlich beschreibt, vs-Arrays.

Um sicher zu sein, dass wir anderen Menschen helfen, die kommen tatsächlich auf der Suche nach Hilfe mit JSON-Arrays, obwohl, es lohnt sich, sie explizit zu behandeln.


Für den sicheren ish Fall, in dem Zeichenketten nicht Zeilenumbrüche enthalten kann (und wenn bash 4.0 oder höher verwendet wird), das funktioniert:

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

Um ältere Versionen von Bash zu unterstützen und Strings mit Zeilenumbrüchen, bekommen wir ein bisschen schicker, einen NUL-getrennten Strom unter Verwendung von jq zu lesen:

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

Dies ist, wie kann es rekursiv durchgeführt werden:

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

es nennen:

get_settings "$SETTINGS_JSON" 

Das Array wird wie so zugegriffen werden:

${SETTINGS[grandparent:parent:child]} 
Verwandte Themen