#! /usr/bin/env python | |
import sys,os,subprocess | |
class Bash2Py(object): __slots__ = ["val"] def __init__(self, value=''): self.val = value def setValue(self, value=None): self.val = value return value | |
def GetVariable(name, local=locals()): if name in local: return local[name] if name in globals(): return globals()[name] return None def Make(name, local=locals()): ret = GetVariable(name, local) if ret is None: ret = Bash2Py(0) globals()[name] = ret return ret def GetValue(name, local=locals()): variable = GetVariable(name,local) if variable is None or variable.val is None: return '' return variable.val def Str(value): if isinstance(value, list): return " ".join(value) if isinstance(value, basestring): return value return str(value) | |
class Expand(object): @staticmethod def at(): if (len(sys.argv) < 2): return [] return sys.argv[1:] @staticmethod def star(in_quotes): if (in_quotes): if (len(sys.argv) < 2): return "" return " ".join(sys.argv[1:]) return Expand.at() @staticmethod def hash(): return len(sys.argv)-1 @staticmethod def colonMinus(name, value=''): ret = GetValue(name) if (ret is None or ret == ''): ret = value return ret @staticmethod def colonPlus(name, value=''): ret = GetValue(name) if (ret is None or ret == ''): return '' return value | |
#!/usr/bin/env bash | |
throw () { echo "$*" >&2 exit 1 } | |
def throw () : print(Expand.star(1),stderr=subprocess.STDOUT) exit(1) | |
BRIEF=0 | |
BRIEF=Bash2Py(0) | |
LEAFONLY=0 | |
LEAFONLY=Bash2Py(0) | |
PRUNE=0 | |
PRUNE=Bash2Py(0) | |
usage() { echo echo "Usage: JSON.sh [-b] [-l] [-p] [-h]" echo echo "-p - Prune empty. Exclude fields with empty values." echo "-l - Leaf only. Only show leaf nodes, which stops data duplication." echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options." echo "-h - This help text." echo } | |
def usage () : print() print("Usage: JSON.sh [-b] [-l] [-p] [-h]") print() print("-p - Prune empty. Exclude fields with empty values.") print("-l - Leaf only. Only show leaf nodes, which stops data duplication.") print("-b - Brief. Combines 'Leaf only' and 'Prune empty' options.") print("-h - This help text.") print() | |
parse_options() { set -- "$@" local ARGN=$# while [ $ARGN -ne 0 ] do case $1 in -h) usage exit 0 ;; -b) BRIEF=1 LEAFONLY=1 PRUNE=1 ;; -l) LEAFONLY=1 ;; -p) PRUNE=1 ;; ?*) echo "ERROR: Unknown option." usage exit 0 ;; esac shift 1 ARGN=$((ARGN-1)) done } | |
def parse_options (_p1) : global BRIEF global LEAFONLY global PRUNE subprocess.call(["set","--",Str(Expand.at())],shell=True) ARGN=Bash2Py(Expand.hash()) while (int(ARGN.val) != 0): if ( str(_p1) == '-h'): usage() exit(0) elif ( str(_p1) == '-b'): Make("BRIEF").setValue(1) Make("LEAFONLY").setValue(1) Make("PRUNE").setValue(1) elif ( str(_p1) == '-l'): Make("LEAFONLY").setValue(1) elif ( str(_p1) == '-p'): Make("PRUNE").setValue(1) elif ( str(_p1) == '?*'): print("ERROR: Unknown option.") usage() exit(0) subprocess.call(["shift","1"],shell=True) Make("ARGN").setValue((ARGN.val - 1)) | |
awk_egrep () { local pattern_string=$1 gawk '{ while ($0) { start=match($0, pattern); token=substr($0, start, RLENGTH); print token; $0=substr($0, start+RLENGTH); } }' pattern=$pattern_string } | |
def awk_egrep (_p1) : Make("pattern_string").setValue(_p1) _rc0 = subprocess.call(["gawk","{\n while ($0) {\n start=match($0, pattern);\n token=substr($0, start, RLENGTH);\n print token;\n $0=substr($0, start+RLENGTH);\n }\n }","pattern="+str(pattern_string.val)],shell=True) | |
tokenize () { local GREP local ESCAPE local CHAR if echo "test string" | egrep -ao --color=never "test" &>/dev/null then GREP='egrep -ao --color=never' else GREP='egrep -ao' fi if echo "test string" | egrep -o "test" &>/dev/null then ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' CHAR='[^[:cntrl:]"\\]' else GREP=awk_egrep ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})' CHAR='[^[:cntrl:]"\\\\]' fi 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:]]+' $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$" } | |
def tokenize () : global GREP global ESCAPE global CHAR "GREP" "ESCAPE" "CHAR" if (_rcr8, _rcw8 = os.pipe() if os.fork(): os.close(_rcw8) os.dup2(_rcr8, 0) subprocess.call("egrep" + " " + "-ao" + " " + "--color=never" + " " + "test",shell=True,stderr=subprocess.STDOUT,stdout=file('/dev/null','wb')) else: os.close(_rcr8) os.dup2(_rcw8, 1) print("test string") sys.exit(0) ): Make("GREP").setValue("egrep -ao --color=never") else: Make("GREP").setValue("egrep -ao") if (_rcr7, _rcw7 = os.pipe() if os.fork(): os.close(_rcw7) os.dup2(_rcr7, 0) subprocess.call("egrep" + " " + "-o" + " " + "test",shell=True,stderr=subprocess.STDOUT,stdout=file('/dev/null','wb')) else: os.close(_rcr7) os.dup2(_rcw7, 1) print("test string") sys.exit(0) ): Make("ESCAPE").setValue("(\\\\[^u[:cntrl:]]|\\\\u[0-9a-fA-F]{4})") Make("CHAR").setValue("[^[:cntrl:]\"\\\\]") else: Make("GREP").setValue("awk_egrep") Make("ESCAPE").setValue("(\\\\\\\\[^u[:cntrl:]]|\\\\u[0-9a-fA-F]{4})") Make("CHAR").setValue("[^[:cntrl:]\"\\\\\\\\]") STRING=Bash2Py("\""+str(CHAR.val)+"*("+str(ESCAPE.val)+str(CHAR.val)+"*)*\"") NUMBER=Bash2Py("-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?") KEYWORD=Bash2Py("null|false|true") SPACE=Bash2Py("[[:space:]]+") _rc0 = _rcr2, _rcw2 = os.pipe() if os.fork(): os.close(_rcw2) os.dup2(_rcr2, 0) subprocess.call(["egrep","-v","^"+str(SPACE.val)+"$"],shell=True) else: os.close(_rcr2) os.dup2(_rcw2, 1) subprocess.call([str(GREP.val),str(STRING.val)+"|"+str(NUMBER.val)+"|"+str(KEYWORD.val)+"|"+str(SPACE.val)+"|."],shell=True) sys.exit(0) | |
parse_array () { local index=0 local ary='' read -r token case "$token" in ']') ;; *) while : do parse_value "$1" "$index" 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 [ "$BRIEF" -eq 0 ] && value=`printf '[%s]' "$ary"` || value= : } | |
def parse_array (_p1) : global token global value global BRIEF Make("index").setValue(0) ary=Bash2Py() token = Bash2Py(raw_input()) if ( str(token.val) == ']'): else: while (pass): subprocess.call(["parse_value",str(_p1),str(index.val)],shell=True) Make("index").setValue((index.val + 1)) Make("ary").setValue(str(ary.val)+str(value.val)) token = Bash2Py(raw_input()) elif ( str(token.val) == ']'): break elif ( str(token.val) == ','): Make("ary").setValue(str(ary.val)+",") else: throw("EXPECTED , or ] GOT "+Expand.colonMinus("token","EOF")) token = Bash2Py(raw_input()) if not if int(BRIEF.val) == 0: Make("value").setValue(os.popen("printf \"[%s]\" \""+str(ary.val)+"\"").read().rstrip("\n")): Make("value").setValue() pass | |
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$key:$value" read -r token case "$token" in '}') break ;; ',') obj="$obj," ;; *) throw "EXPECTED , or } GOT ${token:-EOF}" ;; esac read -r token done ;; esac [ "$BRIEF" -eq 0 ] && value=`printf '{%s}' "$obj"` || value= : } | |
def parse_object (_p1) : global token global key global value global BRIEF "key" obj=Bash2Py() token = Bash2Py(raw_input()) if ( str(token.val) == '}'): else: while (pass): elif ( str(token.val) == ''"'*'"''): Make("key").setValue(token.val) else: throw("EXPECTED string GOT "+Expand.colonMinus("token","EOF")) token = Bash2Py(raw_input()) if ( str(token.val) == ':'): else: throw("EXPECTED : GOT "+Expand.colonMinus("token","EOF")) token = Bash2Py(raw_input()) subprocess.call(["parse_value",str(_p1),str(key.val)],shell=True) Make("obj").setValue(str(obj.val)+str(key.val)+":"+str(value.val)) token = Bash2Py(raw_input()) if ( str(token.val) == '}'): break elif ( str(token.val) == ','): Make("obj").setValue(str(obj.val)+",") else: throw("EXPECTED , or } GOT "+Expand.colonMinus("token","EOF")) token = Bash2Py(raw_input()) if not if int(BRIEF.val) == 0: Make("value").setValue(os.popen("printf \"{%s}\" \""+str(obj.val)+"\"").read().rstrip("\n")): Make("value").setValue() pass | |
parse_value () { local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0 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 isleaf=1 [ "$value" = '""' ] && isempty=1 ;; esac [ "$value" = '' ] && return [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1 [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1 [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1 [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \ [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1 [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value" : } | |
def parse_value (_p1,_p2) : global token global value global LEAFONLY global PRUNE Make("jpath").setValue(Expand.colonPlus("1",str(_p1)+",")+str(_p2)) Make("isleaf").setValue(0) Make("isempty").setValue(0) Make("print").setValue(0) if ( str(token.val) == '{'): parse_object(jpath.val) elif ( str(token.val) == '['): parse_array(jpath.val) elif ( str(token.val) == '' or str(token.val) == '[!0-9]'): # At this point, the only valid single-character tokens are digits. | |
throw("EXPECTED value GOT "+Expand.colonMinus("token","EOF")) else: Make("value").setValue(token.val) Make("isleaf").setValue(1) if value.val "=""\"\"" != '': Make("isempty").setValue(1) if value.val "="str() != '': return if if int(LEAFONLY.val) == 0: int(PRUNE.val) == 0: Make("print").setValue(1) if if if int(LEAFONLY.val) == 1: int(isleaf.val) == 1: int(PRUNE.val) == 0: Make("print").setValue(1) if if if int(LEAFONLY.val) == 0: int(PRUNE.val) == 1: int(isempty.val) == 0: Make("print").setValue(1) if if if if int(LEAFONLY.val) == 1: int(isleaf.val) == 1: int(PRUNE.val) == 1: int(isempty.val) == 0: Make("print").setValue(1) if int(print.val) == 1: print( "[%s]\t%s\n" % (str(jpath.val), str(value.val)) ) pass | |
parse () { read -r token parse_value read -r token case "$token" in '') ;; *) throw "EXPECTED EOF GOT $token" ;; esac } | |
def parse () : global token token = Bash2Py(raw_input()) parse_value() token = Bash2Py(raw_input()) if ( str(token.val) == ''): else: throw("EXPECTED EOF GOT "+str(token.val)) | |
parse_options "$@" | |
parse_options(Expand.at()) | |
if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]); then tokenize | parse fi | |
if ((if not __file__ "="str(BASH_SOURCE.val) != '': not (str(BASH_SOURCE.val) != '')) ): _rcr1, _rcw1 = os.pipe() if os.fork(): os.close(_rcw1) os.dup2(_rcr1, 0) parse() else: os.close(_rcr1) os.dup2(_rcw1, 1) tokenize() sys.exit(0) | |
ÿ |