#!/usr/bin/awk -f ### begin from awkenough (https://github.com/dubiousjim/awkenough) #### function assert(test, msg) { if (!test) die(msg ? msg : "assertion failed") } # if you call die, assert, or check*: start END blocks with # { if (EXITCODE) exit EXITCODE; ... } function die(msg) { EXITCODE=1 printf("%s: %s\n", ARGV[0], msg) > "/dev/stderr" exit EXITCODE } function parse_json(str, T, V, slack, c,s,n,a,A,b,B,C,U,W,i,j,k,u,v,w,root) { # use strings, numbers, booleans as separators # c = "[^\"\\\\[:cntrl:]]|\\\\[\"\\\\/bfnrt]|\\u[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]" c = "[^\"\\\\\001-\037]|\\\\[\"\\\\/bfnrt]|\\\\u[[:xdigit:]A-F][[:xdigit:]A-F][[:xdigit:]A-F][[:xdigit:]A-F]" s ="\"(" c ")*\"" n = "-?(0|[1-9][[:digit:]]*)([.][[:digit:]]+)?([eE][+-]?[[:digit:]]+)?" root = gsplit(str, A, s "|" n "|true|false|null", T) assert(root > 0, "unexpected") # rejoin string using value indices str = "" for (i=1; i 1) return -2 else if (A[1] !~ /^[[:digit:]]+$/) return -3 else return A[1]+0 } # parse objects and arrays k = root C[0] = 0 for (i=2; i<=a; i++) { T[k] = (B[i-1] ~ /\{/) ? "object" : "array" C[k] = C[0] C[0] = k u = gsplit(A[i], U, "[]}]", W) assert(u > 0, "unexpected") V[k++] = U[1] if (i < a && A[i] != "" && U[u] !~ /[,:]$/) return -4 for (j=1; j"/dev/stderr" EXITCODE = 1 exit(1) } if (ARGV[1] == "-h" || ARGV[1] == "--help") { EXITCODE = 0 print USAGE exit(0) } outd = ARGV[1] if (ARGC == 3) { ARGV[1] = ARGV[2] ARGC = 2 } else { ARGC = 1 ARGV[1] = "" } RS = SUBSEP } END { if (EXITCODE != "") { exit(EXITCODE) } ret = query_json($0, data) assert(ret == 0, "failed to parse json\n") for (key in data) { path = key gsub("/", "_", path) gsub(SUBSEP, "/", path) fpath = outd "/" path ret = system("mkdir -p " dirname(fpath)) assert(ret == 0, "failed to mkdir " fpath) printf("%s", data[key]) > fpath } } # vi: ts=4 noexpandtab