0

I'm working on an OpenWRT project where I need to get data from a server. The data is in JSON format and looks something like this:

{"key1":"value1","key2":"value2","key3":"value3"}

I want to parse it to 2 arrays in bash, like this:

keys[0]=key1
keys[1]=key2
keys[2]=key3

values[0]=value1
values[1]=value2
values[2]=value3

I tired jshn.sh, but it only can extract values for known keys.

Kyokai
  • 15
  • 1
  • 6
  • Check out these solutions- sed/awk: http://stackoverflow.com/questions/1955505/parsing-json-with-sed-and-awk or perl: http://stackoverflow.com/questions/3858671/unix-command-line-json-parser – problemPotato Mar 10 '14 at 12:14

4 Answers4

3

I would advise to use jq for solving your problem, but this package might be too heavy for the device you're running openwrt.

The main JSON parser on openwrt is provided by the libubox library. You can use this one to solve your problem.

. /usr/share/libubox/jshn.sh 
json_init
json_load '{"key1":"value1","key2":"value2","key3":"value3"}'
json_get_keys keys
for k in $keys; do 
   json_get_var v "$k"
   echo "$k : $v"
done
oliv
  • 12,690
  • 25
  • 45
0

Using grep and tr:

declare -a keys=($(grep -Eo '"\w+":' json | tr -d \":))
declare -a values=($(grep -Eo ':"\w+"' json | tr -d \":))

Output:

$ for i in 0 1 2; do echo "${keys[$i]} - ${values[$i]}"; done
key1 - value1
key2 - value2
key3 - value3

In this case, I have assumed your JSON data is stored in a file named 'json' - this could be replaced with the output of a command like so:

declare -a keys=($(grep -Eo '"\w+":' <(curl www.example.com/json?q=test) | tr -d \":))
Josh Jolly
  • 11,258
  • 2
  • 39
  • 55
  • I like this solution because of the one-liner keys and values extraction. I changed the "\w+" part in the regexp to "([^"]*)" because i have some special characters in the values. Thanks for your help! – Kyokai Mar 10 '14 at 14:35
  • @Kyokai this solution is a little bit too low level. Since jshn is already installed in OpenWRT by default, http://stackoverflow.com/questions/34955082/jshn-how-to-parse-json-package is perhaps the best option. It will correctly parse JSON objects and nesting – Denis Mysenko Oct 12 '16 at 01:27
0

There are more suitable tools to read json files but you can try below:

    #!/bin/bash

    declare -A arr
    string='{"key1":"value1","key2":"value2","key3":"value3"}'

    while read key value; do
        [[ -n "$key" ]] && arr["$key"]="$value"
    done < <(sed 's/[\"{}]//g' <<< "$string" | awk -F: 'BEGIN{RS=","} {print $1" "$2}')

    for i in ${!arr[@]}; do
        echo "$i -> ${arr[$i]}"
    done
Timmah
  • 2,001
  • 19
  • 18
0

Take a look at jq.

json='{"key1":"value1","key2":"value2","key3":"value3"}'

keys=`echo $json | jq 'keys'`
values=`echo $json | jq '. | [.[]]'`

If you echo "keys: $keys"; echo "values: $values" this returns:

keys: [
  "key1",
  "key2",
  "key3"
]
values: [
  "value3",
  "value2",
  "value1"
]

I've noticed that in most of the Linux distro's I have used jq is included in the package manager. You can install it by performing sudo apt-get install jq or sudo yum install jq, depending on which package manager you use.

Bas Peeters
  • 3,269
  • 4
  • 33
  • 49