feat: Added a custom json extractor

This commit is contained in:
2026-06-25 19:18:13 +05:30
parent b813061e9a
commit 33b98477bf

68
lib/json.sh Normal file
View 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
}
}
}
'
}