-
-
Save budhash/79c12453c641985e5dba8765a4792ab9 to your computer and use it in GitHub Desktop.
Extract a value from a JSON object or array in awk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Extract a JSON value in an object: | |
# | |
# items = get_json_value(json, "payload.tree.items") | |
# | |
# Or in an array: | |
# | |
# while ((item = get_json_value(items, i++))) | |
# name = decode_json_string(get_json_value(item, "name")) | |
# | |
# Or both: | |
# | |
# item = get_json_value(json, "payload.tree.items.0") | |
# | |
function get_json_value(s, key, type, all, rest, nested, isval, i, c, k) { | |
type = substr(s, 1, 1) | |
if (type != "{" && type != "[") error("invalid json array/object " s) | |
all = key == "" && key == 0 | |
if (!all && (i = index(key, "."))) { | |
rest = substr(key, i+1) | |
key = substr(key, 1, i-1) | |
nested = 1 | |
} | |
if (type == "[") k = 0 | |
isval = type == "[" | |
for (i = 2; i < length(s); i += length(c)) { | |
c = substr(s, i, 1) | |
if (c == "\"") { | |
if (!match(substr(s, i), /^"(\\.|[^\\"])*"/)) | |
error("invalid json string " substr(s, i)) | |
c = substr(s, i, RLENGTH) | |
if (!isval) k = substr(c, 2, length(c)-2) | |
} | |
else if (c == "{" || c == "[") { | |
c = (!all && k == key && nested) ? \ | |
get_json_value(substr(s, i), rest) : \ | |
get_json_value(substr(s, i)) | |
} | |
else if (c == "}" || c == "]") break | |
else if (c == ",") isval = type == "[" | |
else if (c == ":") ; | |
else if (c ~ /[[:space:]]/) continue | |
else { | |
if (!match(substr(s, i), /[]},[:space:]]/)) | |
error("invalid json value " substr(s, i)) | |
c = substr(s, i, RSTART-1) | |
} | |
if (!all && k == key && isval) { | |
if (nested && substr(s, i, 1) !~ /[[{]/) return | |
return c | |
} | |
if (type == "{" && c == ":") isval = 1 | |
if (type == "[" && c == ",") ++k | |
} | |
if (all) return substr(s, 1, i) | |
} | |
function decode_json_string(s, out, esc) { | |
if (s !~ /^"./ || substr(s, length(s), 1) != "\"") | |
error("invalid json string " s) | |
s = substr(s, 2, length(s)-2) | |
esc["b"] = "\b"; esc["f"] = "\f"; esc["n"] = "\n"; esc["\""] = "\"" | |
esc["r"] = "\r"; esc["t"] = "\t"; esc["/"] = "/" ; esc["\\"] = "\\" | |
while (match(s, /\\/)) { | |
if (!(substr(s, RSTART+1, 1) in esc)) | |
error("unknown json escape " substr(s, RSTART, 2)) | |
out = out substr(s, 1, RSTART-1) esc[substr(s, RSTART+1, 1)] | |
s = substr(s, RSTART+2) | |
} | |
return out s | |
} | |
function error(msg) { | |
printf "%s: %s\n", ARGV[0], msg > "/dev/stderr" | |
exit 1 | |
} | |
# | |
# Example usage | |
# | |
# $ curl https://httpbin.org/json | awk -f json.awk slideshow.title | |
# "Sample Slide Show" | |
# | |
BEGIN { | |
while (ret = getline l < "/dev/stdin") { | |
if (ret == -1) error("getline error") | |
s = s l | |
} | |
print get_json_value(s, ARGV[1]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment