Skip to content

Instantly share code, notes, and snippets.

@shomah4a
Last active February 7, 2017 02:48
Show Gist options
  • Save shomah4a/5710236e2e97fbbff020b3294a0eb617 to your computer and use it in GitHub Desktop.
Save shomah4a/5710236e2e97fbbff020b3294a0eb617 to your computer and use it in GitHub Desktop.
jqみたいなやつ
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import json
import operator
import re
import sys
ATTR_REG = re.compile(r'\.([a-zA-Z_][a-zA-Z0-9_]*)')
INDEX_REG = re.compile(r'\[(-?[0-9]+)\]')
FILTER_REG = re.compile(r'\[(.+?) *(==|<|>|!=|<=|>=|in|not in) *(.+?)]')
SELF_REG = re.compile(r'_(\.[a-zA-Z_][a-zA-Z0-9_]*)?')
def log(*values):
print(*values, file=sys.stderr)
def attribute(obj, m):
n = m.group(1)
return obj.get(n)
def index(obj, m):
idx = int(m.group(1))
return obj[idx]
OPERATORS = {
'==': operator.eq,
'!=': operator.ne,
'<': operator.lt,
'<=': operator.le,
'>': operator.gt,
'>=': operator.ge,
'in': lambda l, r: operator.contains(r, l),
'not in': lambda l, r: not operator.contains(r, l)
}
def evaluate(obj, value):
m = SELF_REG.match(value)
if m:
attr = m.group(1)
if attr:
return obj[attr.lstrip('.')]
return obj
else:
return json.loads(value)
def filter(obj, m):
left = m.group(1)
op = OPERATORS.get(m.group(2))
right = m.group(3)
log('left:', left)
log('right:', right)
log('operator:', op)
return [x for x in obj if op(evaluate(x, left), evaluate(x, right))]
COMMANDS = [
(ATTR_REG, attribute),
(INDEX_REG, index),
(FILTER_REG, filter)
]
def dispatch(obj, exp):
for reg, f in COMMANDS:
m = reg.match(exp)
if m:
return f(obj, m)
raise ValueError('invalid command: {0}'.format(exp))
def load(f):
if f == '-':
return json.loads(sys.stdin.read())
return json.loads(open(f).read())
def main():
if len(sys.argv) < 2:
print('insufficient arguments', file=sys.stderr)
sys.exit(1)
f = sys.argv[1]
exps = sys.argv[2:]
obj = load(f)
for exp in exps:
obj = dispatch(obj, exp)
print(json.dumps(obj, indent=1, ensure_ascii=False))
if __name__ == '__main__':
main()
@shomah4a
Copy link
Author

shomah4a commented Feb 6, 2017

$ jq.py hoge.json .a '[_ == 10]' '[0]' .b

みたいなことする

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment