5

I m playing with json messages with bash

I have the following json message jmsg:

{
    "var1": "any1",
    "var2": "any2",
    "array-vars": [
                "arrany1",
                "arrany2"
    ]
}

I can load the json message with

$json_init
$json_load "$jmsg"

then I can get the value of var1 and var2 with:

$json_get_var var1 var1
$json_get_var var2 var2

But if I try with the same command to get the array variables

$json_get_var array_vars array-vars
$echo $array_vars
JSON_ARRAY8

How I can extract the array values?

I m using the following script reference for json commands (from libubox):

# functions for parsing and generating json

_json_get_var() {
    local ___dest="$1"
    local ___var="$2"
    eval "$___dest=\"\$${JSON_PREFIX}$___var\""
}

_json_set_var() {
    local ___var="$1"
    local ___val="$2"
    eval "${JSON_PREFIX}$___var=\"\$___val\""
}

_jshn_append() {
    local __var="$1"
    local __value="$2"
    local __sep="${3:- }"
    local __old_val

    _json_get_var __old_val "$__var"
    __value="${__old_val:+$__old_val$__sep}$__value"
    _json_set_var "$__var" "$__value"
}

_json_export() {
    local __var="${JSON_PREFIX}$1"
    local __val="$2"

    export -- "$__var=$__val"
    _jshn_append "JSON_UNSET" "$__var"
}

_json_add_key() {
    local table="$1"
    local var="$2"
    _jshn_append "KEYS_${table}" "$var"
}

_get_var() {
    local __dest="$1"
    local __var="$2"
    eval "$__dest=\"\$$__var\""
}

_set_var() {
    local __var="$1"
    local __val="$2"
    eval "$__var=\"\$__val\""
}

_json_inc() {
    local _var="$1"
    local _dest="$2"
    local _seq

    _json_get_var _seq "$_var"
    _seq="$((${_seq:-0} + 1))"
    _json_set_var "$_var" "$_seq"
    [ -n "$_dest" ] && _set_var "$_dest" "$_seq"
}

_json_stack_push() {
    local new_cur="$1"
    local cur

    _json_get_var cur JSON_CUR
    _jshn_append JSON_STACK "$cur"
    _json_set_var JSON_CUR "$new_cur"
}

_json_add_generic() {
    local type="$1"
    local var="$2"
    local val="$3"
    local cur="$4"

    [ -n "$cur" ] || _json_get_var cur JSON_CUR

    if [ "${cur%%[0-9]*}" = "JSON_ARRAY" ]; then
        _json_inc "SEQ_$cur" var
    else
        local name="${var//[^a-zA-Z0-9_]/_}"
        [[ "$name" == "$var" ]] || _json_export "NAME_${cur}_${name}" "$var"
        var="$name"
    fi

    _json_export "${cur}_$var" "$val"
    _json_export "TYPE_${cur}_$var" "$type"
    _json_add_key "$cur" "$var"
}

_json_add_table() {
    local name="$1"
    local type="$2"
    local itype="$3"
    local cur new_cur
    local seq

    _json_get_var cur JSON_CUR
    _json_inc JSON_SEQ seq

    local table="JSON_$itype$seq"
    _json_export "UP_$table" "$cur"
    _json_export "KEYS_$table" ""
    [ "$itype" = "ARRAY" ] && _json_export "SEQ_$table" ""
    _json_stack_push "$table"

    _json_get_var new_cur JSON_CUR
    _json_add_generic "$type" "$1" "$new_cur" "$cur"
}

_json_close_table() {
    local stack new_stack

    _json_get_var stack JSON_STACK
    _json_set_var JSON_CUR "${stack##* }"
    new_stack="${stack% *}"
    [[ "$stack" == "$new_stack" ]] && new_stack=
    _json_set_var JSON_STACK "$new_stack"
}

json_set_namespace() {
    local _new="$1"
    local _old="$2"

    [ -n "$_old" ] && _set_var "$_old" "$JSON_PREFIX"
    JSON_PREFIX="$_new"
}

json_cleanup() {
    local unset

    _json_get_var unset JSON_UNSET
    [ -n "$unset" ] && eval "unset $unset"

    unset \
        ${JSON_PREFIX}JSON_SEQ \
        ${JSON_PREFIX}JSON_STACK \
        ${JSON_PREFIX}JSON_CUR \
        ${JSON_PREFIX}JSON_UNSET \
        ${JSON_PREFIX}KEYS_JSON_VAR \
        ${JSON_PREFIX}TYPE_JSON_VAR
}

json_init() {
    json_cleanup
    export -- \
        ${JSON_PREFIX}JSON_SEQ=0 \
        ${JSON_PREFIX}JSON_STACK= \
        ${JSON_PREFIX}JSON_CUR="JSON_VAR" \
        ${JSON_PREFIX}JSON_UNSET="" \
        ${JSON_PREFIX}KEYS_JSON_VAR= \
        ${JSON_PREFIX}TYPE_JSON_VAR=
}

json_add_object() {
    _json_add_table "$1" object TABLE
}

json_close_object() {
    _json_close_table
}

json_add_array() {
    _json_add_table "$1" array ARRAY 
}

json_close_array() {
    _json_close_table
}

json_add_string() {
    _json_add_generic string "$1" "$2"
}

json_add_int() {
    _json_add_generic int "$1" "$2"
}

json_add_boolean() {
    _json_add_generic boolean "$1" "$2"
}

# functions read access to json variables

json_load() {
    eval `jshn -r "$1"`
}

json_dump() {
    jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} -w 
}

json_get_type() {
    local __dest="$1"
    local __cur

    _json_get_var __cur JSON_CUR
    local __var="${JSON_PREFIX}TYPE_${__cur}_${2//[^a-zA-Z0-9_]/_}"
    eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
}

json_get_var() {
    local __dest="$1"
    local __cur

    _json_get_var __cur JSON_CUR
    local __var="${JSON_PREFIX}${__cur}_${2//[^a-zA-Z0-9_]/_}"
    eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
}

json_get_vars() {
    while [ "$#" -gt 0 ]; do
        local _var="$1"; shift
        json_get_var "$_var" "$_var"
    done
}

json_select() {
    local target="$1"
    local type
    local cur

    [ -z "$1" ] && {
        _json_set_var JSON_CUR "JSON_VAR"
        return 0
    }
    [[ "$1" == ".." ]] && {
        _json_get_var cur JSON_CUR
        _json_get_var cur "UP_$cur"
        _json_set_var JSON_CUR "$cur"
        return 0
    }
    json_get_type type "$target"
    case "$type" in
        object|array)
            json_get_var cur "$target"
            _json_set_var JSON_CUR "$cur"
        ;;
        *)
            echo "WARNING: Variable '$target' does not exist or is not an array/object"
            return 1
        ;;
    esac
}

json_is_a() {
    local type

    json_get_type type "$1"
    [ "$type" = "$2" ]
}
2
  • 1
    why not use an actual json parsing tool? Commented Dec 18, 2013 at 12:30
  • It would be much better to use a dedicated JSON parser for this. Commented Dec 18, 2013 at 13:19

1 Answer 1

2

Based on this topic

json_init
json_load "$jmsg"

json_select "array-vars"
local Index="1"
while json_get_type type $Index && [ "$type" = string ]; do
        json_get_var arrvar "$((Index++))"
        echo arrvar
done
json_select ".."
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.