0

I have this JSON with measurement data:

{
 "errorCode":0,
"statusDataInfo":{
  "function-status-text-005":{
     "textValue":"2006-0310",
     "type":"basic-text"
  },
  "function-status-text-027":{
     "type":"simple-value",
     "value":"50"
  },
  "function-status-text-049":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-025":{
     "type":"simple-value",
     "value":"43"
  },
  "function-status-text-047":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-068":{
     "type":"simple-value",
     "value":"0"
  },
  "function-status-text-009":{
     "type":"simple-value",
     "value":"22"
  },
  "function-status-text-007":{
     "textValue":"2006-0325",
     "type":"basic-text"
  },
  "function-status-text-029":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-041":{
     "textValue":"2006-0960",
     "type":"basic-text"
  },
  "function-status-text-063":{
     "type":"simple-value",
     "value":"3"
  },
  "function-status-text-060":{
     "type":"simple-value",
     "value":"67"
  },
  "function-status-text-023":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-045":{
     "textValue":"2006-0300",
     "type":"basic-text"
  },
  "function-status-text-021":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-043":{
     "textValue":"2006-0300",
     "type":"basic-text"
  },
  "function-status-text-065":{
     "type":"simple-value",
     "value":"0"
  },
  "function-status-text-015":{
     "type":"simple-value",
     "value":"0"
  },
  "function-status-text-037":{
     "type":"simple-value",
     "value":"1550"
  },
  "function-status-text-058":{
     "type":"simple-value",
     "value":"163"
  },
  "function-status-text-013":{
     "type":"simple-value",
     "value":"22"
  },
  "function-status-text-035":{
     "type":"simple-value",
     "value":"11.22"
  },
  "function-status-text-019":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-017":{
     "type":"simple-value",
     "value":"24"
  },
  "function-status-text-039":{
     "textValue":"2006-0940",
     "type":"basic-text"
  },
  "function-status-text-051":{
     "type":"simple-value",
     "value":""
  },
  "function-status-text-056":{
     "type":"simple-value",
     "value":"0"
  },
  "function-status-text-011":{
     "type":"simple-value",
     "value":"22"
  },
  "function-status-text-031":{
     "type":"simple-value",
     "value":"19"
  },
  "function-status-text-053":{
     "type":"simple-value",
     "value":"-"
      }
   },
   "statusBackgroundDataInfo":{
  "0xA0":{
     "value":"0"
  },
  "0x20":{
     "value":"0"
  },
  "0xE1":{
     "value":"0"
  },
  "0xE0":{
     "value":"1"
  },
  "0xFA":{
     "value":"0"
  },
  "0xF0":{
     "value":"1"
  },
  "0x80":{
     "value":"1"
  },
  "0xF9":{
     "value":"1"
  },
  "0xC4":{
     "value":"0"
     }
  }
}

And what I want is a bash associative array made out of it, where I can just access the values from the JSON like this:

myArray[function-status-text-005][type]
myArray[function-status-text-005][value]

I tried many solutions from Stackoverflow and the web, but I cannot get any to work. Any help would be appreciated

kind regards

EDIT

I tried the solution in this Stackoverflow link but it does not work. It needs a top level array, while mine is neatens in statusDataInfo

EDIT2 Thanks to @Cyrus I got a step further:

jsonValues=$(cat data.json | jq -r '.statusDataInfo | to_entries|map("\(.key)=\(.value)")|.[]')

for i in "${!jsonValues[@]}"
do
  echo "key  : $i"
  echo "value: ${jsonValues[$i]}"
done

ready into an assoc array BUT it has only one key with the corresponding value holding all info from the json:

key  : 0
value: function-status-text-005={"textValue":"2006-0310","type":"basic-text"}
function-status-text-027={"type":"simple-value","value":"50"}
 function-status-text-049={"type":"simple-value","value":""}
 function-status-text-025={"type":"simple-value","value":"43"}
 function-status-text-047={"type":"simple-value","value":""}
 function-status-text-068={"type":"simple-value","value":"0"}
 function-status-text-009={"type":"simple-value","value":"22"}
 function-status-text-007={"textValue":"2006-0325","type":"basic-text"}
 function-status-text-029={"type":"simple-value","value":""}
 function-status-text-041={"textValue":"2006-0960","type":"basic-text"}
 function-status-text-063={"type":"simple-value","value":"3"}
 function-status-text-060={"type":"simple-value","value":"67"}
 function-status-text-023={"type":"simple-value","value":""}
 function-status-text-045={"textValue":"2006-0300","type":"basic-text"}
 function-status-text-021={"type":"simple-value","value":""}
 function-status-text-043={"textValue":"2006-0300","type":"basic-text"}
 function-status-text-065={"type":"simple-value","value":"0"}
 function-status-text-015={"type":"simple-value","value":"0"}
 function-status-text-037={"type":"simple-value","value":"1550"}
 function-status-text-058={"type":"simple-value","value":"163"}
 function-status-text-013={"type":"simple-value","value":"22"}
 function-status-text-035={"type":"simple-value","value":"11.22"}
 function-status-text-019={"type":"simple-value","value":""}
 function-status-text-017={"type":"simple-value","value":"24"}
 function-status-text-039={"textValue":"2006-0940","type":"basic-text"}
 function-status-text-051={"type":"simple-value","value":""}
 function-status-text-056={"type":"simple-value","value":"0"}
 function-status-text-011={"type":"simple-value","value":"22"}
 function-status-text-031={"type":"simple-value","value":"19"}
 function-status-text-053={"type":"simple-value","value":"-"}
gutenmorgenuhu
  • 2,312
  • 1
  • 19
  • 33
  • Post those efforts into the question! – Inian Oct 21 '19 at 07:30
  • Is [this](https://stackoverflow.com/questions/26717277/converting-a-json-object-into-a-bash-associative-array) what you're looking for? – Alice Oct 21 '19 at 07:38
  • I thank you for this comment. Unfortunately I tried this and it and it produces an empty output (the solution you linked needs a top-level array, while mine is nested) – gutenmorgenuhu Oct 21 '19 at 07:42
  • Are `textValue` and `value` present along with `type`? They could occur inter related? – Inian Oct 21 '19 at 07:55
  • When `"type"="basic-text"`then you have a `textValue`. In the other cases you have a `value` – gutenmorgenuhu Oct 21 '19 at 07:57
  • This might help: `jq -r '.statusDataInfo | to_entries|map("\(.key)=\(.value)")|.[]' file` – Cyrus Oct 21 '19 at 08:22
  • Thank you for the comment. I edited my question with your hint. The problem is, that this command does not create the correct keys in the array but instead makes an array with one key (0) and the value holds the complete info from the json – gutenmorgenuhu Oct 21 '19 at 08:37
  • bash arrays are one-dimensional. – Andrew Vickers Oct 21 '19 at 14:49
  • In the future, please post the minimal amount of data that illustrates the problem. Wouldn't less than 10 lines of data been sufficient to demonstrate your problem? Good luck. – shellter Oct 21 '19 at 17:20
  • Save yourself a *lot* of trouble: choose a language other than `bash` that supports real data structures. – chepner Oct 21 '19 at 20:41

2 Answers2

1

myArray[function-status-text-005][type]

myArray[function-status-text-005][value]

I tried many solutions from Stackoverflow and the web, but I cannot get any to work

That's because bash does not support that kind of indexing, as illustrated by the following:

$ echo $BASH_VERSION
5.0.7(1)-release
$ declare -A ary
$ ary["a"]=("x" "y z")
bash: ary["a"]: cannot assign list to array member

For "workarounds" and alternatives, see e.g.

Multi-dimensional arrays in Bash

Since your data has only two "types", you might want to consider one of the simplest options: having two associative arrays. So instead of writing:

myArray[function-status-text-005][type]

you'd write something like:

type[function-status-text-005]
Community
  • 1
  • 1
peak
  • 105,803
  • 17
  • 152
  • 177
1

As pointed out, bash does not support 2-dim array. Then how about having two arrays: type[] and value[].
Would you please try the following:

#!/bin/bash

declare -A type value
pat='^(.+)=\{"([^"]*)":"([^"]*)","([^"]*)":"([^"]*)"\}'
while IFS= read -r line; do
    if [[ $line =~ $pat ]]; then
        key="${BASH_REMATCH[1]}"
        if [[ ${BASH_REMATCH[2]} = "type" ]]; then
            type[$key]="${BASH_REMATCH[3]}"
            value[$key]="${BASH_REMATCH[5]}"
        else
            type[$key]="${BASH_REMATCH[5]}"
            value[$key]="${BASH_REMATCH[3]}"
        fi
    fi
done < <(jq -r '.statusDataInfo|to_entries|map("\(.key)=\(.value|tostring)")|.[]' file.json)

# show the contents of the arrays
for i in "${!type[@]}"; do
    printf "%s = %s, %s\n" "$i" "${type[$i]}" "${value[$i]}"
done

Hope this helps.

tshiono
  • 21,248
  • 2
  • 14
  • 22
  • To the downvoter: I'd appreciate if I can hear your frank opinion why you felt unconfortable with my answer for my future reference. BR. – tshiono Oct 23 '19 at 01:32