Skip to content

Instantly share code, notes, and snippets.

@pranavraja
Created April 26, 2018 05:15
Show Gist options
  • Save pranavraja/390c02a22e7cda8eb00642efe5b9b51c to your computer and use it in GitHub Desktop.
Save pranavraja/390c02a22e7cda8eb00642efe5b9b51c to your computer and use it in GitHub Desktop.
Simpler version of jq

Ok jq is great but sometimes i just need to select/filter a field or two

Example usage:

$ curl https://now.httpbin.org | json now rfc3339
"2018-04-26T05:10:00.78Z"

$ echo '[{"id": 1, "title":"Hello"}, {"id": 2, "title":"Goodbye"}]' | json title=Hello id
[
  1
]

$ echo '[{"id": 1, "title":"Hello"}, {"id": 2, "title":"Goodbye"}]' | json title=Hello id
[
  1
]

$ echo '[{"id": 1, "title":"123456789"}, {"id": 2, "title":"Goodbye"}, {"id": 3, "title": "987765"}]' | json 'title~\d+' id
[
  1,
  3
]
#!/usr/bin/env python
import json
import sys
import re
from operator import eq
def getin(val, field):
path = field.split('.')
for p in path:
if not val: return
if isinstance(val, list) and p.isdigit() and len(v) > int(p):
val = val[int(p)]
elif isinstance(val, dict):
val = val.get(p)
return val
def matches(v, key, filter, matchfunc):
if key.isdigit(): key = int(key)
result = getin(v, key)
if not result: return False
if isinstance(result, list):
return any(matchfunc(filter, r) for r in result)
else:
return matchfunc(filter, result)
def pluck(fieldspec, val):
if ',' in fieldspec:
fields = fieldspec.split(',')
return {field: getin(val, field) for field in fields}
else:
return getin(val, fieldspec)
val = json.load(sys.stdin)
for arg in sys.argv[1:]:
if '~' in arg:
key, filter = arg.split('~')
val = [v for v in val if matches(v, key, filter, re.search)]
elif '=' in arg:
key, filter = arg.split('=')
val = [v for v in val if matches(v, key, filter, eq)]
elif isinstance(val, list):
val = [pluck(arg, v) for v in val]
else:
val = pluck(arg, val)
print json.dumps(val, indent=2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment