Skip to main content

fs/cdir.py

1#!/usr/bin/env python3
2"""
3This script prints a short table of the subdirectories with the most entries,
4plus the total number of entries in a directory. It's useful if I'm trying
5to clean up a disk, and I'm looking for directories where I can make quick
6and easy gains.
8 37 fishconfig
9 48 repros
10 51 colossus-wheels
11 70 services
12 292 .git
13 -------
14 699
16It's also useful for finding the directory that's making backup software
17unhappy because there's lots of filesystem activity (e.g. `node_modules`).
19I often use this in conjunction with DaisyDisk (https://daisydiskapp.com/),
20which breaks down directories by size.
22This script takes an optional argument, which is the path to the directory
23to scan. Running ``cdir`` will scan the current directory; ``cdir <DIR>`` will
24scan the directory ``DIR``.
26"""
28import collections
29import os
30import sys
32import tqdm
35def count_entries_under(d):
36 with tqdm.tqdm(desc=d, leave=False) as pbar:
37 total = 1
39 for _, dirnames, filenames in os.walk(d):
40 update = len(dirnames) + len(filenames)
42 total += update
43 pbar.update(update)
45 return total
48if __name__ == "__main__":
49 prefixes = collections.Counter()
51 try:
52 root = sys.argv[1]
53 except IndexError:
54 root = "."
56 for e in os.listdir(root):
57 pth = os.path.join(root, e)
58 if os.path.isdir(pth):
59 prefixes[e] = count_entries_under(pth)
60 else:
61 prefixes["."] += 1
63 for prefix, count in reversed(prefixes.most_common()):
64 print("%7d\t%s" % (count, prefix))
66 home_display = os.path.abspath(root).replace(os.environ["HOME"], "~")
68 print("-------")
69 print("%7d\t%s" % (sum(prefixes.values()), home_display))