Add my script for flattening directory hierarchies
- ID
e8ddd7f- date
2022-04-26 22:52:50+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
b6e9d32- message
Add my script for flattening directory hierarchies- changed files
1 file, 69 additions
Changed files
flatten (0) → flatten (1716)
diff --git a/flatten b/flatten
new file mode 100755
index 0000000..1416cbd
--- /dev/null
+++ b/flatten
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+"""
+Run inside a directory, and it moves every non-trivial file up to the
+top-level.
+
+I use this to flatten out heavily-nested directory hierarchies, when I need
+to sort through the files by hand and want to see what I've got.
+
+It tries to handle cases where different files exist with the same name, but
+it may not be robust. Use with caution.
+
+By default it only prints what it's going to do, you need to add the flag `--run`
+for it to do anything.
+"""
+
+import filecmp
+import os
+import secrets
+import shutil
+import sys
+
+
+def mv(src, dst):
+ print(f'mv {src} ~> {dst}')
+ if '--run' in sys.argv:
+ os.rename(src, dst)
+
+
+def rm(path):
+ print(f'rm {path}')
+ if '--run' in sys.argv:
+ os.unlink(path)
+
+
+if __name__ == '__main__':
+ for root, _, filenames in os.walk('.'):
+ if root == '.':
+ continue
+
+ for f in filenames:
+ f_src = os.path.join(root, f)
+
+ if f == '.DS_Store':
+ rm(f_src)
+ continue
+
+ f_dst = f
+
+ if os.path.exists(f_dst) and filecmp.cmp(f_src, f_dst):
+ rm(f_src)
+ continue
+
+ # Add a bit of noise to filenames to avoid duplication
+ while os.path.exists(f_dst):
+ name, ext = os.path.splitext(f)
+ f_dst = name + '__' + secrets.token_hex(3) + ext
+
+ mv(src=f_src, dst=f_dst)
+
+ # Clean up empty directories
+ while True:
+ is_finished = True
+ for root, dirnames, filenames in os.walk('.'):
+ if not dirnames and not filenames:
+ shutil.rmtree(root)
+ is_finished = False
+
+ if is_finished:
+ break