forked from dominictarr/JSON.sh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
JSON.sh
executable file
·123 lines (116 loc) · 2.59 KB
/
JSON.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
if isatty && [ ! -z "$(which isatty)" ];then
TXT_BLD=$(tput bold)
TXT_RED=$(tput setaf 1)
TXT_GREEN=$(tput setaf 2)
TXT_YLW=$(tput setaf 3)
TXT_BLUE=$(tput setaf 4)
TXT_PURPLE=$(tput setaf 5)
TXT_CYAN=$(tput setaf 6)
TXT_WHITE=$(tput setaf 7)
TXT_RESET=$(tput sgr0)
else
TXT_BLD=
TXT_RED=
TXT_GREEN=
TXT_YLW=
TXT_BLUE=
TXT_PURPLE=
TXT_CYAN=
TXT_WHITE=
TXT_RESET=
fi
throw () {
echo "$*" >&2
exit 1
}
tokenize () {
local ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
local CHAR='[^[:cntrl:]"\\]'
local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
local KEYWORD='null|false|true'
local SPACE='[[:space:]]+'
egrep -ao "$STRING|$NUMBER|$KEYWORD|$SPACE|." --color=never |
egrep -v "^$SPACE$" # eat whitespace
}
parse_array () {
local index=0
local ary=''
read -r token
case "$token" in
']') ;;
*)
while :
do
parse_value "$1" "$index"
let index=$index+1
ary="$ary""$value"
read -r token
case "$token" in
']') break ;;
',') ary="$ary," ;;
*) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=`printf '[%s]' $ary`
}
parse_object () {
local key
local obj=''
read -r token
case "$token" in
'}') ;;
*)
while :
do
case "$token" in
'"'*'"') key=$token ;;
*) throw "EXPECTED string GOT ${token:-EOF}" ;;
esac
read -r token
case "$token" in
':') ;;
*) throw "EXPECTED : GOT ${token:-EOF}" ;;
esac
read -r token
parse_value "$1" "$key"
obj="$obj$TXT_BLUE$key$TXT_RESET:$TXT_RED$value$TXT_RESET"
read -r token
case "$token" in
'}') break ;;
',') obj="$obj," ;;
*) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=`printf '{%s}' "$obj"`
}
parse_value () {
local jpath="${1:+$1,}$2"
case "$token" in
'{') parse_object "$jpath" ;;
'[') parse_array "$jpath" ;;
# At this point, the only valid single-character tokens are digits.
''|[^0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
*) value=$token ;;
esac
printf "[%s]\t%s\n" "$TXT_GREEN$jpath$TXT_RESET" "$TXT_PURPLE$value$TXT_RESET"
}
parse () {
read -r token
parse_value
read -r token
case "$token" in
'') ;;
*) throw "EXPECTED EOF GOT $token" ;;
esac
}
if [ $0 = $BASH_SOURCE ];
then
tokenize | parse
fi