jsonpath.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/usr/bin/python
  2. # encoding: utf-8
  3. # Copyright © 2012 Felix Richter <wtfpl@syntax-fehler.de>
  4. # This work is free. You can redistribute it and/or modify it under the
  5. # terms of the Do What The Fuck You Want To Public License, Version 2,
  6. # as published by Sam Hocevar. See the COPYING file for more details.
  7. # Use modern Python
  8. from __future__ import unicode_literals, print_function, absolute_import
  9. # Standard Library imports
  10. import json
  11. import sys
  12. import glob
  13. import argparse
  14. # JsonPath-RW imports
  15. from jsonpath_rw import parse
  16. def find_matches_for_file(expr, f):
  17. return expr.find(json.load(f))
  18. def print_matches(matches):
  19. print('\n'.join(['{0}'.format(match.value) for match in matches]))
  20. def main(*argv):
  21. parser = argparse.ArgumentParser(
  22. description='Search JSON files (or stdin) according to a JSONPath expression.',
  23. formatter_class=argparse.RawTextHelpFormatter,
  24. epilog="""
  25. Quick JSONPath reference (see more at https://github.com/kennknowles/python-jsonpath-rw)
  26. atomics:
  27. $ - root object
  28. `this` - current object
  29. operators:
  30. path1.path2 - same as xpath /
  31. path1|path2 - union
  32. path1..path2 - somewhere in between
  33. fields:
  34. fieldname - field with name
  35. * - any field
  36. [_start_?:_end_?] - array slice
  37. [*] - any array index
  38. """)
  39. parser.add_argument('expression', help='A JSONPath expression.')
  40. parser.add_argument('files', metavar='file', nargs='*', help='Files to search (if none, searches stdin)')
  41. args = parser.parse_args(argv[1:])
  42. expr = parse(args.expression)
  43. glob_patterns = args.files
  44. if len(glob_patterns) == 0:
  45. # stdin mode
  46. print_matches(find_matches_for_file(expr, sys.stdin))
  47. else:
  48. # file paths mode
  49. for pattern in glob_patterns:
  50. for filename in glob.glob(pattern):
  51. with open(filename) as f:
  52. print_matches(find_matches_for_file(expr, f))
  53. def entry_point():
  54. main(*sys.argv)