几千个素材要分给几个人、一批图片要拆成多份分批上传、数据集要按比例分成训练集和验证集——这类"把一堆文件平均分到多个文件夹"的活,手工拖拽能做但极慢且容易错。这篇讲三种做法。
这些场景有两个共同要求:不能重复、不能遗漏。手工操作最容易在这两点上出错。
文件少的时候(几十个)这样做没问题:
文件一多就废了,原因不是慢,是容易错:
Windows 自带 PowerShell,可以直接写脚本处理。
$src = "C:源文件夹"
$dst = "C:目标文件夹"
$perFolder = 100
$files = Get-ChildItem -Path $src -File
$i = 0
$folderIndex = 1
$target = ""
foreach ($f in $files) {
if ($i % $perFolder -eq 0) {
$target = Join-Path $dst ("part_" + $folderIndex)
New-Item -ItemType Directory -Force -Path $target | Out-Null
$folderIndex++
}
Copy-Item $f.FullName -Destination $target
$i++
}
Write-Host "完成,共处理 $i 个文件"
$src = "C:源文件夹"
$dst = "C:目标文件夹"
$folderCount = 5
$files = Get-ChildItem -Path $src -File
$idx = 0
foreach ($f in $files) {
$n = ($idx % $folderCount) + 1
$target = Join-Path $dst ("part_" + $n)
New-Item -ItemType Directory -Force -Path $target | Out-Null
Copy-Item $f.FullName -Destination $target
$idx++
}
这种写法是轮流分配(第1个进part_1、第2个进part_2……),余数会自动摊到前面几个文件夹,分得最均匀。
数据集拆分这类场景需要打乱顺序,加一行排序即可:
$files = Get-ChildItem -Path $src -File | Sort-Object { Get-Random }
$files = Get-ChildItem -Path $src -File | Where-Object { $_.Extension -in ".jpg", ".png" }
上面几段脚本都能用,但实际跑一批重要文件之前,要知道它们的短板:
Copy-Item 遇到同名文件默认直接覆盖,不提示。源文件夹有子目录、不同子目录里有同名文件时,会悄无声息地丢数据Copy-Item 换成 Move-Item 后,一旦中途出错,文件已经离开源目录,恢复很麻烦睿君文件平均分配工具就是把上面这些规则做成了界面选项:
几个脚本里比较难做的点它是支持的:
| 对比项 | 手工拖拽 | PowerShell | 专用工具 |
|---|---|---|---|
| 费用 | 免费 | 免费 | 付费 |
| 文件量 | 几十个以内 | 不限 | 不限 |
| 按类型筛选 | 手动挑 | 改代码 | 勾选 |
| 随机分配 | 做不到 | 加一行 | 切换选项 |
| 双规则叠加 | 做不到 | 要自己写逻辑 | 支持 |
| 重名保护 | 有提示 | 默认覆盖 | 有处理 |
| 出错代价 | 高 | 高(尤其移动模式) | 低 |
第一:先用复制,不要直接用移动。复制完核对无误,再决定要不要删源文件。移动模式虽然快、省空间,但出错就是不可逆的。重要文件尤其如此。
第二:分完一定要核对总数。把各个目标文件夹的文件数加起来,跟源文件夹对比。PowerShell 里一行就能查:
Get-ChildItem -Path "C:目标文件夹" -Recurse -File | Measure-Object | Select-Object Count
数字对不上,说明有重名覆盖或漏分,趁早发现。
Q:文件数除不尽怎么办?比如 1003 个文件分 5 份?
轮流分配的方式会自动把余数摊到前面几个文件夹,结果是 3 个文件夹 201 个、2 个文件夹 200 个,这是最均匀的分法。
Q:源文件夹里有子文件夹,会一起处理吗?
上面的脚本默认只处理当前层级。要包含子目录得加 -Recurse,但那样很容易出现不同子目录下的同名文件互相覆盖,加之前先确认没有重名。
Q:能不能按文件大小平均,而不是按数量?
按体积均分是另一个问题(本质上是装箱问题),上面的脚本做不到,需要先读取每个文件大小再分配。多数场景按数量分就够了。
Q:分完想还原怎么办?
用复制模式的话,源文件夹原封不动,直接删掉目标文件夹即可。这也是建议优先用复制的原因。
86998867
微信同号
