Python 脚本清理 WorkBuddy 空文件夹:定时任务自动删除空目录

背景

在使用 WorkBuddy 一段时间后,我发现工作目录下堆积了大量空文件夹。这些空目录可能是项目删除后残留的,也可能是某些工具自动生成后未清理的。手动一个个删除太麻烦,于是写了一个 Python 脚本来批量清理。

脚本功能

这个脚本有以下特点:

代码实现

"""清理当前用户 WorkBuddy 目录下的空文件夹(含级联后的空父目录)。

规则:
- 只删除「整棵子树不含任何文件」的目录,目录内只要有文件就一律不动。
- 跳过路径中含 .git / node_modules / app.asar.unpacked 的目录。
- 不加 --apply 只扫描出报告,不删除。
- 删除结果追加写入日志文件。

用法:
    python clean-empty-dirs.py            # 只扫描
    python clean-empty-dirs.py --apply    # 扫描并删除
"""
import os
import sys
from datetime import datetime

USER_HOME = os.path.expanduser("~")
ROOT = os.path.join(USER_HOME, "WorkBuddy")
LOG_FILE = os.path.join(USER_HOME, ".workbuddy", "logs", "clean-empty-dirs.log")
SKIP_SEGMENTS = {".git", "node_modules", "app.asar.unpacked"}


def skipped(path):
    """检查路径是否包含需要跳过的目录段"""
    return bool(SKIP_SEGMENTS & set(path.split(os.sep)))


def log(line):
    """输出到控制台并追加写入日志文件"""
    print(line)
    try:
        os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
        with open(LOG_FILE, "a", encoding="utf-8") as f:
            f.write(line + "\n")
    except OSError:
        pass


def main():
    """主函数:扫描空目录并根据参数决定是否删除"""
    apply = "--apply" in sys.argv

    # 第一轮:直接为空的目录
    empty = []
    total_dirs = 0
    for cwd, dirs, files in os.walk(ROOT):
        total_dirs += len(dirs)
        for d in dirs:
            full = os.path.join(cwd, d)
            if skipped(full):
                continue
            try:
                if not os.listdir(full):
                    empty.append(full)
            except OSError as e:
                log(f"[跳过] {full} -> {e}")
    empty_set = set(empty)

    # 迭代:子目录被删后父目录也可能变空(父目录本身仍不含任何文件)
    changed = True
    while changed:
        changed = False
        for cwd, dirs, files in os.walk(ROOT):
            if files or cwd == ROOT or skipped(cwd):
                continue
            try:
                remaining = [n for n in os.listdir(cwd)
                             if os.path.join(cwd, n) not in empty_set]
            except OSError:
                continue
            if not remaining and cwd not in empty_set:
                empty_set.add(cwd)
                changed = True

    stamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    targets = sorted(empty_set, key=len, reverse=True)
    mode = "删除" if apply else "扫描"
    log(f"--- {stamp} {mode}开始 | 目录总数 {total_dirs} | 命中 {len(targets)} ---")
    for p in sorted(empty_set):
        log(("  [删] " if apply else "  [空] ") + p)

    if apply:
        ok, fail = 0, 0
        for p in targets:
            try:
                os.rmdir(p)  # 只能删空目录,非空会直接报错,不会误删
                ok += 1
            except OSError as e:
                fail += 1
                log(f"  [失败] {p} -> {e}")
        log(f"--- 完成: 成功 {ok}, 失败 {fail} ---")
    else:
        log(f"--- 扫描完成,未删除任何目录(加 --apply 才会删)---")


if __name__ == "__main__":
    main()

使用方法

1. 只扫描(预览模式)

python clean-empty-dirs.py

这会列出所有空目录,但不会删除任何东西。

2. 扫描并删除

python clean-empty-dirs.py --apply

这会真正删除空目录,并记录到日志文件。

设置 WorkBuddy 定时任务

把脚本保存好,然后告诉 WorkBuddy 设置一个定时任务,每周清理一次空文件夹。WorkBuddy 会自动帮你配置好定时任务。

对话示例

在 WorkBuddy 中输入:帮我设置一个定时任务,每周执行一次 f:\code\Python\clean-empty-dirs.py –apply,清理空文件夹。

WorkBuddy 会自动创建定时任务,每周定期运行脚本,清理 WorkBuddy 目录下的空文件夹。

好处

日志位置

脚本运行日志保存在:

%USERPROFILE%\.workbuddy\logs\clean-empty-dirs.log

可以查看日志了解每次清理的结果。

  • All rights reserved.
  • No part of this website, including text and images, may be reproduced, modified, distributed, or transmitted in any form or by any means, without the prior written permission of the author.
  • Unauthorized commercial use is strictly prohibited.
  • Unauthorized personal use is strictly prohibited.