basic json parser in pure bash

This commit is contained in:
olli 2024-03-28 17:33:19 +01:00
parent d1c32d32c6
commit e687cd8dfb

77
gaboshlib/g_json.sh Normal file
View File

@ -0,0 +1,77 @@
#!/bin/bash
# thanks to dylanaraps - https://github.com/dylanaraps/nosj
# function g_json gives back the associative array $g_json
# parsed json by stdin or file in $1
#
# To get keys use: ${!g_json[@]}
# To get values use ${g_json[@]}
# To get specifi key use ${g_json[keyname]}
function g_json {
IFS= g_json_tokenize < "${1:-/dev/stdin}"
IFS= g_json_parse
}
function g_json_tokenize {
local j str
while read -rN 1; do
case $REPLY in
[\{\}\[\],])
[[ $str ]] && j+=$REPLY
[[ $str ]] || { tokens+=("$j" "$REPLY"); j=; }
;;
:)
[[ $str ]] && j+=:
[[ $str ]] || j+='\ '
;;
[[:space:]])
[[ $str ]] && j+=$REPLY
;;
[\"\'])
[[ $str ]] && str= || str=1
[[ ${j: -1} == \\ ]] && { str=1; j+=$REPLY; }
;;
*) j+=$REPLY ;;
esac
done
}
function g_json_parse {
local i key key_plain objects o val out
declare -Ag g_json
for ((i=0;i<${#tokens[@]};i++)) {
case ${tokens[i]} in
\{|\[)
objects+=("${tokens[i-1]}")
;;
\}|\])
unset 'objects[-1]'
;;
*\\\ *)
key=${objects[*]//\\ /.}${tokens[i]/\\ *}
key_plain=index_${key//[^A-Za-z0-9]/_}
val=${tokens[i]/*\\ }
if [[ -n ${g_json[$key]} ]]
then
[[ -n ${g_json[${key}[0]]} ]] || {
g_json["${key}[0]"]=${g_json[$key]}
printf -v o 'g_json[%q]=%q' "${key}[0]" "${g_json[$key]}"
out+=("$o")
}
declare -i "$key_plain+=1"
printf -v o 'g_json[%q]=%q' "${key}[${!key_plain}]" "$val"
out+=("$o")
elif [[ $val ]]; then
g_json["$key"]=$val
printf -v o 'g_json[%q]=%q' "$key" "$val"
out+=("$o")
fi
;;
esac
}
}
g_json /tmp/json