如何用PowerShell查找并自动删除重复剧集的低质量版本?
这问题我太熟了!之前帮朋友批量清理过剧集重复文件,用PowerShell完全能自动化搞定,还能精准保留高质量版本,避免手动删错。下面一步步来实操:
第一步:先明确规则
首先得统一质量优先级(行业通用排序,按从高到低):
WEB-DL > WEBRip > HDTV
- WEB-DL是直接从流媒体平台提取的源文件,质量最高
- WEBRip是对流媒体内容录屏转码的版本,次之
- HDTV是从电视信号录制的版本,质量相对最低
同时先过滤常见视频格式,避免误处理非视频文件,比如.mkv, .mp4, .avi, .mov, .flv。
第二步:提取剧集核心标识(关键是识别同一集)
要把同一集的不同版本归为一组,核心是从文件名里提取「剧集名称+季集号」的唯一标识。比如Game.of.Thrones.S01E01.WEB-DL.1080p.mkv和Game.of.Thrones.S01E01.HDTV.720p.mkv,核心标识都是Game.of.Thrones.S01E01。
用正则表达式来匹配提取,代码如下:
# 替换成你的剧集目录路径 $targetDir = "D:\TV Shows\Game of Thrones" # 匹配常见剧集命名的正则(支持SXXEXX格式,比如S01E01) $coreNameRegex = '^(.*?)(S\d{2}E\d{2})(.*?)$' # 获取目录下的视频文件 $videoFiles = Get-ChildItem -Path $targetDir -File | Where-Object { $_.Extension -in '.mkv', '.mp4', '.avi', '.mov', '.flv' } # 按核心标识分组 $groupedEpisodes = $videoFiles | Group-Object -Property { $match = [regex]::Match($_.BaseName, $coreNameRegex) if ($match.Success) { # 提取核心标识:剧集名称+季集号,忽略版本后缀 ($match.Groups[1].Value.Trim() + $match.Groups[2].Value).Trim() } else { # 如果匹配失败(比如命名格式特殊),用原文件名分组避免漏处理 $_.BaseName } }
第三步:评估每组质量,标记待删除文件
遍历每个剧集分组,给每个文件打质量分,保留最高分的版本,其余标记为待删除:
# 定义质量分数(数字越高优先级越高) $qualityScores = @{ 'WEB-DL' = 3 'WEBRip' = 2 'HDTV' = 1 } $toDelete = @() foreach ($group in $groupedEpisodes) { if ($group.Count -le 1) { # 只有一个版本,不需要处理 continue } # 给每个文件打质量分 $scoredFiles = $group.Group | ForEach-Object { $score = 0 # 检查文件名里的版本关键字 foreach ($quality in $qualityScores.Keys) { if ($_.BaseName -match $quality) { $score = $qualityScores[$quality] break } } # 返回带分数的文件对象 [PSCustomObject]@{ File = $_ Score = $score } } # 找到最高分的文件(要保留的版本) $maxScore = $scoredFiles.Score | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum $keepCandidates = $scoredFiles | Where-Object { $_.Score -eq $maxScore } # 如果有多个同最高分的文件(比如两个WEB-DL但分辨率不同),保留分辨率更高的 if ($keepCandidates.Count -gt 1) { $keepCandidates = $keepCandidates | Sort-Object { if ($_.File.BaseName -match '(\d{3,4}p)') { [int]$matches[1].Replace('p','') } else { 0 } } -Descending | Select-Object -First 1 } # 把非保留文件加入待删除列表 $toDelete += $scoredFiles | Where-Object { $_.File -ne $keepCandidates.File } | Select-Object -ExpandProperty File }
第四步:预览并执行删除
重中之重:先预览待删除文件,确认无误再执行实际删除!
# 预览待删除文件 Write-Host "=== 待删除文件预览 ===" -ForegroundColor Yellow $toDelete | ForEach-Object { Write-Host "- $($_.FullName)" } # 确认无误后,取消下面两行的注释执行删除(-WhatIf是模拟删除,去掉才会实际删除) # Write-Host "=== 开始删除 ===" -ForegroundColor Red # $toDelete | Remove-Item -WhatIf
额外注意事项
- 如果你的剧集是
1x01这种季集格式,把正则改成^(.*?)(\d{1,2}x\d{1,2})(.*?)$即可 - 如果有BluRay等更高质量的版本,在
$qualityScores里添加'BluRay' = 4就行 - 若文件名里没有明确的版本关键字,代码会给它打0分,这类文件会被优先保留(避免误删未知质量的文件)
内容的提问来源于stack exchange,提问作者Mark




