feat: Added a custom json extractor
This commit is contained in:
68
lib/json.sh
Normal file
68
lib/json.sh
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# generic JSON parser in pure bash and awk.
|
||||
# reads JSON from stdin and outputs a flattened list of key-value pairs.
|
||||
# example input: {"plugins": {"my_plugin": {"version": "1.0", "arr": [1, 2]}}}
|
||||
# example output:
|
||||
# plugins.my_plugin.version="1.0"
|
||||
# plugins.my_plugin.arr[0]=1
|
||||
# plugins.my_plugin.arr[1]=2
|
||||
|
||||
# pardon my french
|
||||
parse_json() {
|
||||
# Tokenize the JSON using grep
|
||||
grep -oE '"([^"\\]|\\.)*"|true|false|null|[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?|[{}[\]:,]' | \
|
||||
awk '
|
||||
BEGIN {
|
||||
depth=0;
|
||||
key=""
|
||||
}
|
||||
{
|
||||
token = $0
|
||||
if (token == "{") {
|
||||
depth++
|
||||
is_key[depth] = 1
|
||||
array_idx[depth] = ""
|
||||
} else if (token == "}") {
|
||||
delete path[depth]
|
||||
delete array_idx[depth]
|
||||
depth--
|
||||
} else if (token == "[") {
|
||||
depth++
|
||||
is_key[depth] = 0
|
||||
array_idx[depth] = 0
|
||||
} else if (token == "]") {
|
||||
delete array_idx[depth]
|
||||
delete path[depth]
|
||||
depth--
|
||||
} else if (token == ":") {
|
||||
is_key[depth] = 0
|
||||
} else if (token == ",") {
|
||||
if (array_idx[depth] != "") {
|
||||
array_idx[depth]++
|
||||
} else {
|
||||
is_key[depth] = 1
|
||||
}
|
||||
} else {
|
||||
if (is_key[depth] == 1) {
|
||||
# Remove quotes from the key
|
||||
gsub(/^"|"$/, "", token)
|
||||
path[depth] = token
|
||||
} else {
|
||||
# It is a value
|
||||
p = ""
|
||||
for (i=1; i<=depth; i++) {
|
||||
if (array_idx[i] != "") {
|
||||
p = p "[" array_idx[i] "]"
|
||||
} else if (path[i] != "") {
|
||||
p = p "." path[i]
|
||||
}
|
||||
}
|
||||
# Remove leading dot
|
||||
sub(/^\./, "", p)
|
||||
print p "=" token
|
||||
}
|
||||
}
|
||||
}
|
||||
'
|
||||
}
|
||||
Reference in New Issue
Block a user