Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

return as environment variable #37

Open
waleedsamy opened this issue Dec 23, 2015 · 5 comments
Open

return as environment variable #37

waleedsamy opened this issue Dec 23, 2015 · 5 comments

Comments

@waleedsamy
Copy link

i use JSON.sh as curl 'http://conf.com/conf/config_20150920_test.json' | ./JSON.sh -l -p -b -s and it work greet and it return result like

["storage","mysql","u_db","database"]   "dev"
["storage","mysql","u_db","username"]   "user"
["storage","mysql","u_db","password"]   "123@1"
["storage","mysql","u_db","internal_ip"]    "10.176.192.120"
["storage","mysql","u_db","internal_port"]  3306
["storage","mysql","a","database"]  "a"
["storage","mysql","a","username"]  "user"
["storage","mysql","a","password"]  "122a@1"

but what if add config param to determine how output look like and go with exporting this variables as env variables like

storage_mysql_u_db_internal_port=3306
storage_mysql_a_database=a
storage_mysql_a_username=user
storage_mysql_a_password=122a@1

which make it easy to be evaluated with eval as environment variable.

@Tomaskom-cz
Copy link

Not exactly what you're asking for, but I use the following two functions for extracting values from the JSON.sh output:

#function to get value of specified key
#returns empty string if not found
#warning - does not validate key format (supplied as parameter) in any way, simply returns empty string for malformed queries too
#usage: VAR=$(getkey foo.bar) #get value of "bar" contained within "foo"
#       VAR=$(getkey foo[4].bar) #get value of "bar" contained in the array "foo" on position 4
#       VAR=$(getkey [4].foo) #get value of "foo" contained in the root unnamed array on position 4
function getkey {
    #reformat key string (parameter) to what JSON.sh uses
    KEYSTRING=$(sed -e 's/\[/\"\,/g' -e 's/^\"\,/\[/g' -e 's/\]\./\,\"/g' -e 's/\./\"\,\"/g' -e '/^\[/! s/^/\[\"/g' -e '/\]$/! s/$/\"\]/g' <<< "$@")
    #extract the key value
    FOUT=$(grep -F "$KEYSTRING" <<< "$JSON_PARSED")
    FOUT="${FOUT#*$'\t'}"
    FOUT="${FOUT#*\"}"
    FOUT="${FOUT%\"*}"
    echo "$FOUT"
}

#function returning length of array
#returns zero if key in parameter does not exist or is not an array
#usage: VAR=$(getarrlen foo.bar) #get length of array "bar" contained within "foo"
#       VAR=$(getarrlen) #get length of the root unnamed array
#       VAR=$(getarrlen [2].foo.bar) #get length of array "bar" contained within "foo", which is stored in the root unnamed array on position 2
function getarrlen {
    #reformat key string (parameter) to what JSON.sh uses
    KEYSTRING=$(sed -e '/^\[/! s/\[/\"\,/g' -e 's/\]\./\,\"/g' -e 's/\./\"\,\"/g' -e '/^$/! {/^\[/! s/^/\[\"/g}' -e '/^$/! s/$/\"\,/g' -e 's/\[/\\\[/g' -e 's/\]/\\\]/g' -e 's/\,/\\\,/g' -e '/^$/ s/^/\\\[/g' <<< "$@")
    #extract the key array length - get last index
    LEN=$(grep -o "${KEYSTRING}[0-9]*" <<< "$JSON_PARSED" | tail -n -1 | grep -o "[0-9]*$")
    #increment to get length, if empty => zero
    if [ -n "$LEN" ]; then
        LEN=$(($LEN+1))
    else
        LEN="0"
    fi
    echo "$LEN"
}

It expects the JSON.sh to be run with the -l flag and output stored in the variable $JSON_PARSED.

Also, using eval as you suggested can be dangerous if the output is improperly escaped. For example, string "; rm -rf /" in the JSON data could lead to disaster.

@decibel
Copy link
Contributor

decibel commented May 30, 2016

So how about adding these to JSON.sh itself? That way you could source it, parse the json once and query away.

@decibel
Copy link
Contributor

decibel commented May 30, 2016

Also, how would you get a list of keys in an object?

@Tomaskom-cz
Copy link

Depends on the format you'd like. If the subset of JSON structure is OK for you, just use it without the -l option and specify a "path" to the object in question. In this case, my code snippet should give you this substructure.
If you really want a simple list of strings, you could re-parse this subset with JSON.sh and just extract (grep + regex) the first key strings on each line from the output, removing duplicates.

@gnadelwartz
Copy link

gnadelwartz commented May 22, 2019

Hi,

I also was looking for a solution to "slurp" JSON.sh output into an bash array.
if you output only the leafs with JSON.sh -s -b -n this will do the trick:

source <( printf 'declare -A JSON=( %s )' "$(JSON.sh -s -b -n <input | sed  -E -e 's/\t/=/g' -e 's#\\#\\\\#g')" )

this will be sourced "in place" as:

declare -A JSON=( ["ok"]="true" ["result",0,"update_id"]=146860800 ["result",0,"message","message_id"]=6541 ["result",0,"message","text"]="\\ud83d\\ude02\\ud83d\\ude1d\\ud83d\\udc4c\\u263a\\u2764\\ud83d\\ude15\\ud83d\\ude08#\\u20e3\\ud83c\\udf0f\\ud83c\\udf89\\ud83d\\ude4a\\ud83d\\ude49\\u2615\\ud83d\\ude80\\u2708\\ud83d\\ude82\\ud83d\\udcaf\\u2714\\u303d\\ud83d\\udd1a" ["result",0,"message","from","id"]=123456789 ["result",0,"message","from","is_bot"]="false" ["result",0,"message","from","first_name"]="Kay" ["result",0,"message","from","last_name"]="M" ["result",0,"from","username"]="Gnadelwartz" ["result",0,"message","from","language_code"]="de" ["result",0,"message","chat","id"]=123456789 ["result",0,"message","chat","first_name"]="Test" ["result",0,"message","chat","last_name"]="Bot" ["result",0,"message","chat","username"]="BotTest" ["result",0,"message","chat","title"]="BotTestTitle" ["result",0,"message","chat","type"]="private" ["result",0,"message","date"]=1555822879 )

Now you can use bash array syntax to access the values:

echo ${JSON[ok]}
true

echo ${JSON["result",0,"message","message_id"]}
6541

echo ${JSON["result",0,"update_id"]}
146860800

echo ${JSON["result",0,"message","from","username"]}
Gnadelwartz

echo ${JSON["result",0,"message","photo",4,"file_id"]}
AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABDsKqM0vfngJavgDAAEC

In bashbot this makes parsing and assigning JSON five times faster

In case you want to ask how to iterate over the array, see https://stackoverflow.com/questions/3112687/how-to-iterate-over-associative-arrays-in-bash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
@decibel @waleedsamy @gnadelwartz @Tomaskom-cz and others