diff options
-rwxr-xr-x | dot_local/bin/jflatten.py | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/dot_local/bin/jflatten.py b/dot_local/bin/jflatten.py new file mode 100755 index 0000000..bacc754 --- /dev/null +++ b/dot_local/bin/jflatten.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +import argparse +import json +import sys + + +def flatten(*path, obj): + if isinstance(obj, list): + for n, value in enumerate(obj): + yield from flatten(*path, n, obj=value) + elif isinstance(obj, dict): + for key, value in obj.items(): + yield from flatten(*path, key, obj=value) + else: + yield path, obj + + +def path_str(*path): + return "".join( + f"[{part}]" if isinstance(part, int) else f".{part}" for part in path + ) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--sort-keys", "-s", action="store_true") + parser.add_argument("--json", "-j", action="store_true") + parser.add_argument("file", nargs="?") + args = parser.parse_args() + + if args.file: + with open(args.file) as f: + data = json.load(f) + else: + data = json.load(sys.stdin) + + flattened = flatten(obj=data) + if args.sort_keys: + flattened = sorted(flattened) + flattened_fmt = ((path_str(*path), value) for path, value in flattened) + + if args.json: + print(json.dumps(dict(flattened_fmt), indent=True)) + else: + print("\n".join(f"{path}:{value}" for path, value in flattened_fmt)) + + +if __name__ == "__main__": + main() |