diff options
author | Alen <alen@dotfiles.xyz> | 2023-09-24 20:25:53 +0400 |
---|---|---|
committer | Alen <alen@dotfiles.xyz> | 2023-09-24 20:25:53 +0400 |
commit | 58cd3774267bbe0b13dd6dd2505f4cd260cb5984 (patch) | |
tree | a8f58c3f2c7d5d965df039fbc1d4e93cef3b118b | |
parent | 89087c9239d03cd4c9c4420e77f296f32a1214c4 (diff) |
Add simple JSON flattening utility
-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() |