如何用PowerShell保留最大尺寸子文件夹,删除同前缀冗余子文件夹
保留同组文件夹中尺寸最大项,删除其余
我的文件夹结构如下:
carlo | +--- Stephen King | +-- 22_11_63 (19989) 22_11_63 (39129) 22_11_63 (59966) | +-- IT (589) IT (2893) | +-- A. Ribaudo | +-- Guidare sicuri (3859) Guidare sicuri (39068)
举例说明:22_11_63 (19989)文件夹大小为2MB,22_11_63 (39129)为1MB,最后一个为500KB;A. Ribaudo下的子文件夹也类似,每个子文件夹大小不同。我需要仅保留每组名称仅括号内内容不同的子文件夹中尺寸最大的,删除其余子文件夹。
我目前使用的PowerShell脚本仅能将父文件夹folder2(sergio)中的缺失子文件夹迁移到父文件夹folder1(carlo),无法实现保留最大尺寸子文件夹的需求,脚本如下:
# Set the path to the two folders to compare $folder1 = "C:\Users\Administrator\Desktop\confronto\carlo" $folder2 = "C:\Users\Administrator\Desktop\confronto\sergio" # Get the list of folders in each folder $folders1 = Get-ChildItem -Path $folder1 -Directory $folders2 = Get-ChildItem -Path $folder2 -Directory # Loop through the folders in $folder2 $folders2 | ForEach-Object { $folder2Name = $_.Name $folder2Path = $_.FullName $folder1Path = Join-Path -Path $folder1 -ChildPath $folder2Name # Check if the folder exists in $folder1 if (Test-Path -Path $folder1Path) { # The folder exists in both folders, so check if it has the same subfolders $subfolders2 = Get-ChildItem -Path $folder2Path -Directory $subfolders1 = Get-ChildItem -Path $folder1Path -Directory $missingIn1 = Compare-Object -ReferenceObject $subfolders1 -DifferenceObject $subfolders2 -Property Name -PassThru # Move the missing subfolders to $folder1 $missingIn1 | ForEach-Object { $subfolderSource = $_.FullName $subfolderDest = Join-Path -Path $folder1Path -ChildPath $_.Name Copy-Item -Path $subfolderSource -Destination $subfolderDest -Recurse } # Remove duplicate subfolders from $folder1 $subfolders1 = Get-ChildItem -Path $folder1Path -Directory $subfoldersToKeep = @() $subfolders1 | Group-Object -Property Name | ForEach-Object { $subfoldersGroup = $_.Group $largestSubfolder = $subfoldersGroup | Sort-Object -Property Length -Descending | Select-Object -First 1 $subfoldersToKeep += $largestSubfolder } $subfolders1 | Where-Object { $subfoldersToKeep -notcontains $_ } | Remove-Item -Recurse } }
期望得到的最终文件夹结构如下:
carlo | +--- Stephen King | +-- 22_11_63 (19989) | +-- IT (2893) | +-- A. Ribaudo | +-- Guidare sicuri (3859)
解决方案脚本
核心逻辑:
- 遍历
carlo下的所有作者文件夹 - 对每个作者文件夹内的子文件夹,按括号前的名称分组(如所有
22_11_63 (...)归为一组) - 计算每组内每个文件夹的实际内容总大小(注意:文件夹本身的
Length属性仅代表元数据大小,需遍历文件求和) - 保留组内内容最大的文件夹,删除其余
最终脚本:
$rootPath = "C:\Users\Administrator\Desktop\confronto\carlo" # 获取所有作者文件夹 $authorFolders = Get-ChildItem -Path $rootPath -Directory foreach ($authorFolder in $authorFolders) { $subfolders = Get-ChildItem -Path $authorFolder.FullName -Directory # 按括号前的名称分组,去掉末尾的"(数字)"部分作为分组键 $groupedFolders = $subfolders | Group-Object -Property { $_.Name -replace '\s*\(\d+\)$', '' } foreach ($group in $groupedFolders) { # 组内只有一个文件夹时直接跳过 if ($group.Count -le 1) { continue } # 计算每个文件夹的内容总大小,排序后取最大项 $largestFolder = $group.Group | ForEach-Object { $totalSize = (Get-ChildItem -Path $_.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum [PSCustomObject]@{ Folder = $_ TotalSize = $totalSize } } | Sort-Object -Property TotalSize -Descending | Select-Object -First 1 # 删除组内除最大文件夹外的所有项,-WhatIf为模拟删除,确认后可移除 $group.Group | Where-Object { $_.FullName -ne $largestFolder.Folder.FullName } | Remove-Item -Recurse -Force -WhatIf } }
注意事项:
- 脚本中的
-WhatIf参数会模拟删除操作,不会实际改动文件,确认逻辑正确后再移除该参数 - 执行前务必备份数据,避免误删重要内容
- 若仅需比较文件夹元数据大小(而非内容总大小),可将计算大小的逻辑替换为直接使用
$_.Length
内容的提问来源于stack exchange,提问作者Jack Rock
相关产品推荐
相关产品推荐

