【收集】你电脑里有没有一件"每个月都要手动重复做一遍"的操作?我挑几个场景写成免费小工具

我是个爱写小脚本的人,之前在这个论坛分享过两个:按"年-月"归档下载文件夹的小脚本、批量导出 Word 里所有图片的脚本(搜我用户名能找到,都是免安装、纯本地的)。

最近想继续练手,顺便多攒几个真实场景的案例,所以来收集需求:

你有没有那种"每个月/每周都要手动重复做一遍"的电脑操作?

比如:

  • 定期整理某个文件夹、批量改名
  • 从一堆 Word/Excel/PDF 里导出或汇总数据
  • 各种格式之间的转换
  • 重复的备份、搬运、去重

规则先说清楚:

  1. 我挑几个自己能做的场景,写成免安装的小工具,免费发回这个论坛;
  2. 不收费、不留联系方式、不加好友;
  3. 做不了的就直说做不了,不耽误大家时间;
  4. 如果论坛里已经有现成工具能解决,也欢迎直接告诉我,我替提问的人谢谢你们。

一句话描述你的场景就行(在哪、什么文件、想变成什么样),越具体越有可能被做成工具。

3 个赞

我每周会用 FreeFileSync 做一次文件备份。它逐个文件比对,有变化的文件才会复制到备份硬盘。

现在有些不舒服的是 .git 目录,里面小文件很多,每次扫描、比对都挺耗时间。

如果能做个小工具,在备份前自动找到这些 .git 目录,分别打包成 Zip,之后让 FreeFileSync 只备份 Zip,不再逐个扫描 .git 里的小文件,这对我很实用。

人肉古法AI?

1 个赞

@kat 这个场景能做,写好了——纯标准库,不用装任何东西。

思路:备份前跑一次,它递归找到所有 .git 目录,各自打包成 目录名.git.zip(放在仓库旁边)。然后你在 FreeFileSync 的排除过滤器里加上 .git\,备份就只处理 zip,不再逐个扫描上万个小文件。想还原某个仓库时 --restore 一条命令解回来。

安全设计:

  • 默认预览模式(列出找到的仓库和体积),加 --apply 才真正打包;
  • 绝不删除或改动 .git 原目录——zip 打坏了源头还在;
  • zip 已存在跳过不覆盖(--overwrite 才重打)。

用法:

python git_pack.py "D:\我的项目"                # 预览
python git_pack.py "D:\我的项目" --apply        # 打包所有 .git
python git_pack.py --restore "路径\xxx.git.zip" # 还原

完整代码(~100 行,保存为 git_pack.py):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
r"""git_pack.py —— 备份加速:把散落的 .git 目录各自打包成 zip(纯标准库)"""
import argparse
import sys
import zipfile
from pathlib import Path


def find_git_dirs(root: Path):
    """递归找 .git 目录;找到后不再进入其内部"""
    found = []
    for cur, dirs, files in __import__('os').walk(root):
        curp = Path(cur)
        for d in list(dirs):
            if d == ".git":
                found.append(curp / d)
                dirs.remove(d)
    return found


def dir_stats(p: Path):
    n, size = 0, 0
    for f in p.rglob("*"):
        if f.is_file():
            n += 1
            size += f.stat().st_size
    return n, size


def human(n):
    for u in ("B", "KB", "MB", "GB"):
        if n < 1024:
            return f"{n:.0f}{u}" if u == "B" else f"{n:.1f}{u}"
        n /= 1024
    return f"{n:.1f}TB"


def do_pack(git_dir: Path, overwrite: bool) -> str:
    out = git_dir.parent / (git_dir.parent.name + ".git.zip")
    if out.exists() and not overwrite:
        return f"跳过(已存在):{out.name}"
    with zipfile.ZipFile(out, "w", zipfile.ZIP_DEFLATED) as z:
        for f in sorted(git_dir.rglob("*")):
            if f.is_file():
                z.write(f, f.relative_to(git_dir.parent).as_posix())
    return f"已打包:{git_dir} -> {out.name}({human(out.stat().st_size)})"


def do_restore(zip_path: Path):
    with zipfile.ZipFile(zip_path) as z:
        z.extractall(zip_path.parent)
    print(f"已还原:{zip_path.name} -> {zip_path.parent}\.git")


def main():
    ap = argparse.ArgumentParser(description="把所有 .git 目录打包成 zip(备份加速)")
    ap.add_argument("folder", nargs="?", help="要扫描的项目根文件夹")
    ap.add_argument("--apply", action="store_true", help="真正打包(默认只预览)")
    ap.add_argument("--overwrite", action="store_true", help="已存在的 zip 也重新打包")
    ap.add_argument("--restore", help="把指定的 .git.zip 还原回 .git 目录")
    args = ap.parse_args()

    if args.restore:
        do_restore(Path(args.restore))
        return

    root = Path(args.folder or input("请输入项目根文件夹路径:").strip().strip('"'))
    if not root.is_dir():
        print("文件夹不存在")
        sys.exit(1)

    gits = find_git_dirs(root)
    if not gits:
        print("没有找到任何 .git 目录。")
        return

    print(f"【预览】找到 {len(gits)} 个 .git 目录:")
    for g in gits:
        n, size = dir_stats(g)
        print(f"    {g}  ({n} 个文件,{human(size)})")
    if not args.apply:
        print("未做任何改动;加 --apply 打包。")
        return

    for g in gits:
        print(do_pack(g, args.overwrite))
    print("完成。提示:在 FreeFileSync 排除过滤器里加上 .git\,备份就只会处理这些 zip 了。")


if __name__ == "__main__":
    main()

发布前自测(9 项断言全过):两个表头不同的仓库(一个嵌套在深层目录、一个含中文名文件)+ 一个干扰 zip 的夹具:预览精确找到 2 个仓库且不动文件、打包后源 .git 原封不动、zip 内容字节一致(含中文名)、重复运行自动跳过不覆盖、–restore 还原字节一致、空目录友好提示。

一个诚实的说明:zip 里只打包 .git 的内容(工作区文件本来就不在 .git 里,也不需要备份);如果你还有"连工作区一起打包"的需求,说一声我改一版。

2 个赞

mac平台可以做么

py 脚本的话,我觉得问题不大。

zipGit.avif

:heart: 老铁给我写的脚本,真的很好用

1 个赞

@dawn 可以,脚本只用标准库,mac/linux 直接跑:python3 git_pack.py 你的目录 --apply(新版 macOS 终端里输 python3 会自动提示装命令行工具,一路回车就行)。还原就加 --restore。

感谢,不过想了想我的需求,mac下的pinginfoview和netsetman,脚本并不能满足我的需求,还是继续将就用着自己用ai写的软件吧。
不管怎么样先谢过了

呃,本地git仓库直接push到远程仓库就好了吧,不需要FreeFileSync来做备份啊
或者每次备份前git gc就能把小文件全打包成大文件了,不需要做成单独打包的zip啊

感谢提醒,这么做是为了多一处备份

每天更新一下scoop软件源?


不过这个每天都会这么搞,不是每月搞一次

这个操作估计比较简单了,先是scoop update,完成后用scoop status查看有更新的软件。

在Debian、Ubuntu之类用apt的系统里,除了新立德包管理器外,GNOME、KDE之类的桌面环境自带的应用商店软件也有deb支持,都是拿来做类似这样的事情的

他那边是两个硬盘之间同步一份备份,push 到远程算不上一份独立的吧。zip 就是让 FreeFileSync 别去扫 .git 里那些小文件,原目录不动,--restore 就能还原。你说的 gc 也够用,看场景。

这个不用写脚本的,scoop update 完看一眼 scoop status,要升就 scoop update *。

但是有时候觉得太简单的事也让ai做,有点浪费token

同感。我现在尽量自己想明白了再让它动手,不然省下来的时间又都花在改它写的东西上,更亏。