2014-11-03 22 views
9

Mam skrypt Bash. Dostaje dane w JSON. Potrzebuję przekonwertować tablicę JSON do tablicy Bash.Konwertowanie tablicy JSON na tablicę Bash

Przykład

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

w bash Chcę uzyskać wartość jak ten echo ${arr[SOMETHING]}.

+0

próbuję użyć 'jq -r” .param_name'' ale swoją pracę tylko wtedy, gdy znać nazwę param – Evgenii

+1

Jeśli twój skrypt otrzyma arbitralny JSON, może to być niemożliwe do wykonania w czystej bash. – helpermethod

Odpowiedz

15

Jeśli chcesz klucz i wartość, a na podstawie How do i convert a json object to key=value format in JQ, można zrobić:

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

W sposób bardziej ogólny, można przechowywać wartości do tablicy myarray[key] = value tak, po prostu poprzez dostarczanie jq do while ze składnią while ... 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) 

a następnie można pętli wartości tak:

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

Z tego danego wejścia, zwraca: pytanie

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

Po prostu wziął element root i dodał go do tablicy. To nie jest rekurencyjne. – PhoenixNoor

+0

@PhoenixNoor, proszę spojrzeć na moją odpowiedź w sposób rekursywny: https://stackoverflow.com/a/47026579/720323 – HelpNeeder

4

PO jest rzeczywiście opisuje obiekty, VS tablic.

Aby być pewnym, że pomagamy innym osobom, które są w rzeczywistości szukasz pomocy z tablicami JSON, warto je jednak wyraźnie zakryć.


do bezpiecznego-owski przypadku gdy ciągi nie może zawierać znaki nowej linii (i kiedy bash 4.0 lub nowsza jest w użyciu), to działa:

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

celu wspierania starszych wersji bash i Struny z nowej linii, możemy uzyskać nieco bardziej wyszukane, wykorzystując NUL-ograniczony strumień odczytać z 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

ten sposób można to zrobić rekurencyjnie:

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

nazwać:

get_settings "$SETTINGS_JSON" 

Tablica będą dostępne tak:

${SETTINGS[grandparent:parent:child]} 
Powiązane problemy