Shell Json编程

参考:https://www.jianshu.com/p/3898f3b6e8e9

#此文用于shell脚本解析和创建json文件(需要系统内部有支持libubox,同时有/usr/share/libubox/jshn.sh)

Test json file:

 cat test.json 
{
        "name": "Linda",
        "age": "21",
        "address": "Xiamen",
        "hobby": 
        [
                {
                        "sport": "sing",
                        "note": "love you forever"
                },
                {
                        "sport": "basketball",
                        "note": "Kobe"
                }
        ],
        "family": {
                "farther": "Haby",
                "mother": "Lanly",
                "sister": "monily"
        }
}

1. Shell script of parsing json file 

#!/bin/sh

. /lib/functions.sh
# it need system support libubox
. /usr/share/libubox/jshn.sh

#load json file
json_load "`/bin/cat /test.json`"

#directly read name & age
json_get_var name_value name
json_get_var age_value age
echo "****name:$name_value**age:$age_value*******">/dev/console

#output: ****name:Linda**age:21*******

#read array
json_select hobby
# array first index is 1
json_select 1
json_get_var sport_value sport
json_get_var note_value note
echo "******sport:$sport_value**note:$note_value*************"
#output: ******sport:sing**note:love you forever*************

#read all arrays via loop
json_select ..
index=1
while json_get_type status $index && [ "$status" = "object" ];do
json_select $index
json_get_var sport_value sport
json_get_var note_value note
echo "***index:$index***sport:$sport_value**note:$note_value*************"
json_select ..
index=$((index+1))
done
#output:***index:1***sport:sing**note:love you forever*************
#       ***index:2***sport:basketball**note:Kobe*************

#read next json object
#return to first layer object:test.
json_select ..
json_select family
json_get_var farther_value farther
json_get_var mother_value mother
json_get_var sister_value sister
echo "***farther:$farther_value**moterh:$mother_value***sister:$sister_value************"

#output:#output: ******sport:sing**note:love you forever*************


shell script all output:

****name:Linda**age:21*******
******sport:sing**note:love you forever*************
***index:1***sport:sing**note:love you forever*************
***index:2***sport:basketball**note:Kobe*************
***farther:Haby**moterh:Lanly***sister:monily************

2. Create json file

#!/bin/sh

. /usr/share/libubox/jshn.sh

json_init
json_add_string "rate" "100Mbps"
json_add_int "number"  100
json_add_boolean "status" 1
json_add_object "device" 
json_add_string "name" "Test-PC"
json_select ..
json_add_array  "user"
json_add_string "" "Test1"
json_add_string "" "Test2"
json_dump>/test
json_dump



3. Create json file(have json object in array json)

json shell script

#!/bin/sh

. /usr/share/libubox/jshn.sh

json_init
json_add_string "rate" "100Mbps"
json_add_int "number"  100
json_add_boolean "status" 1
json_add_object "device" 
json_add_string "name" "Test-PC"
json_select ..
json_add_array  "user"
json_add_object 
json_add_string "1" "Test1"
json_add_string "2" "Test2"
json_select ..
json_add_object 
json_add_string "1" "Test1"
json_add_string "2" "Test2"
json_select ..
json_dump>



#!/bin/sh

. /lib/functions.sh
. /usr/share/libubox/jshn.sh


json_init
json_add_array aa
json_select ..
json_add_array bb
json_select ..
json_add_array cc
json_select ..
json_select aa
json_add_object
json_add_string "a" "a1"
json_add_string "a" "a1"
json_select ..
json_select ..
json_select cc
json_add_object
json_add_string "c" "c1"
json_add_string "c" "c2"
json_select ..
json_dump

output

{ 
    "rate": "100Mbps", 
    "number": 100, 
    "status": true, 
    "device": { 
        "name": "Test-PC" 
    }, 
    "user": [ 
        { 
            "1": "Test1",
            "2": "Test2" 
        }, 
        {
             "1": "Test1",
             "2": "Test2" 
          } 
    ] 
}

     

output

{ 
    "rate": "100Mbps",
    "number": 100, 
    "status": true, 
    "device": { 
        "name": "Test-PC" 
    }, 
    "user": 
        [ 
            "Test1",
             "Test2"
        ]
}





{ 
    "aa": 
    [ 
    { "a": "a1" } 
       ], 
    "bb": [ ], 
    "cc": [ 
    { "c": "c2" } 
        ] 
}

有坑:

在shell中json的命令不能与以下while使用:

#!/bin/sh

. /lib/functions.sh
. /usr/share/libubox/jshn.sh

json_init

a=`ls /tmp/samba//`
json_add_array xxx
echo "$a"|while read line;do

        json_add_object
        json_add_string "test" "value"
        json_select ..
        json_dump
done
json_select ..
json_add_string "test2" "value2"

json_dump

输出结果如下:

{ "xxx": [ { "test": "value" } ] }
{ "xxx": [ { "test": "value" }, { "test": "value" } ] }
{ "xxx": [ ], "test2": "value2" }

发现坑没有,  坑爹啊,前面加进去的json内容没了啊;总结 echo “$para”|while read line这个语句是跟json冲突的。可以使用以下语句替代;

ls /tmp/samba/ >/tmp/samba

while read line;do

json_add_object

....

done </tmp/samba

以上为第一个屎坑,以踩,希望别人别踩~ 真臭~

/usr/share/libubox/jshn.sh

/usr/share/libubox/jshn.sh
# functions for parsing and generating json

_json_get_var() {
        # dest=$1
        # var=$2
        eval "$1=\"\$${JSON_PREFIX}$2\""
}

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

__jshn_raw_append() {
        # var=$1
        local value="$2"
        local sep="${3:- }"

        eval "export -- \"$1=\${$1:+\${$1}\${value:+\$sep}}\$value\""
}

_jshn_append() {
        # var=$1
        local _a_value="$2"
        eval "${JSON_PREFIX}$1=\"\${${JSON_PREFIX}$1} \$_a_value\""
}

_get_var() {
        # var=$1
        # value=$2
        eval "$1=\"\$$2\""
}

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

_json_inc() {
        # var=$1
        # dest=$2

        let "${JSON_PREFIX}$1 += 1" "$2 = ${JSON_PREFIX}$1"
}

_json_add_generic() {
        # type=$1
        # name=$2
        # value=$3
        # cur=$4

        local var
        if [ "${4%%[0-9]*}" = "J_A" ]; then
                _json_inc "S_$4" var
        else
                var="${2//[^a-zA-Z0-9_]/_}"
                [[ "$var" == "$2" ]] || export -- "${JSON_PREFIX}N_${4}_${var}=$2"
        fi

        export -- \
                "${JSON_PREFIX}${4}_$var=$3" \
                "${JSON_PREFIX}T_${4}_$var=$1"
        _jshn_append "JSON_UNSET" "${4}_$var"
        _jshn_append "K_$4" "$var"
}

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

        _json_get_var cur JSON_CUR
        _json_inc JSON_SEQ seq

        local table="J_$3$seq"
        _json_set_var "U_$table" "$cur"
        export -- "${JSON_PREFIX}K_$table="
		
		
        unset "${JSON_PREFIX}S_$table"
        _json_set_var JSON_CUR "$table"
        _jshn_append "JSON_UNSET" "$table"

        _json_add_generic "$2" "$1" "$table" "$cur"
}

_json_close_table() {
        local _s_cur

        _json_get_var _s_cur JSON_CUR
        _json_get_var "${JSON_PREFIX}JSON_CUR" "U_$_s_cur"
}

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

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

json_cleanup() {
        local unset tmp

        _json_get_var unset JSON_UNSET
        for tmp in $unset J_V; do
                unset \
                        ${JSON_PREFIX}U_$tmp \
                        ${JSON_PREFIX}K_$tmp \
                        ${JSON_PREFIX}S_$tmp \
                        ${JSON_PREFIX}T_$tmp \
                        ${JSON_PREFIX}N_$tmp \
                        ${JSON_PREFIX}$tmp
        done

        unset \
                ${JSON_PREFIX}JSON_SEQ \
                ${JSON_PREFIX}JSON_CUR \
                ${JSON_PREFIX}JSON_UNSET
}

json_init() {
        json_cleanup
        export -n ${JSON_PREFIX}JSON_SEQ=0
        export -- \
                ${JSON_PREFIX}JSON_CUR="J_V" \
                ${JSON_PREFIX}K_J_V=
}

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

json_close_object() {
        _json_close_table
}

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

json_close_array() {
        _json_close_table
}

json_add_string() {
        local cur
        _json_get_var cur JSON_CUR
        _json_add_generic string "$1" "$2" "$cur"
}

json_add_int() {
        local cur
        _json_get_var cur JSON_CUR
        _json_add_generic int "$1" "$2" "$cur"
}

json_add_boolean() {
        local cur
        _json_get_var cur JSON_CUR
        _json_add_generic boolean "$1" "$2" "$cur"
}

json_add_double() {
        local cur
        _json_get_var cur JSON_CUR
        _json_add_generic double "$1" "$2" "$cur"
}

# 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}T_${__cur}_${2//[^a-zA-Z0-9_]/_}"
        eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
}

json_get_keys() {
        local __dest="$1"
        local _tbl_cur

        if [ -n "$2" ]; then
                json_get_var _tbl_cur "$2"
        else
                _json_get_var _tbl_cur JSON_CUR
        fi
        local __var="${JSON_PREFIX}K_${_tbl_cur}"
        eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
}

json_get_values() {
        local _v_dest="$1"
        local _v_keys _v_val _select=
        local _json_no_warning=1

        unset "$_v_dest"
        [ -n "$2" ] && {
                json_select "$2" || return 1
                _select=1
        }

        json_get_keys _v_keys
        set -- $_v_keys
        while [ "$#" -gt 0 ]; do
                json_get_var _v_val "$1"
                __jshn_raw_append "$_v_dest" "$_v_val"
                shift
        done
        [ -n "$_select" ] && json_select ..

        return 0
}



json_get_vars() {
        while [ "$#" -gt 0 ]; do
                local _var="$1"; shift
                if [ "$_var" != "${_var#*:}" ]; then
                        json_get_var "${_var%%:*}" "${_var%%:*}" "${_var#*:}"
                else
                        json_get_var "$_var" "$_var"
                fi
        done
}

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

        [ -z "$1" ] && {
                _json_set_var JSON_CUR "J_V"
                return 0
        }
        [[ "$1" == ".." ]] && {
                _json_get_var cur JSON_CUR
                _json_get_var cur "U_$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"
                ;;
                *)
                        [ -n "$_json_no_warning" ] || \
                                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" ]
}

猜你喜欢

转载自blog.csdn.net/llanlianggui/article/details/108010715
今日推荐