You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用PowerShell查找并自动删除重复剧集的低质量版本?

这问题我太熟了!之前帮朋友批量清理过剧集重复文件,用PowerShell完全能自动化搞定,还能精准保留高质量版本,避免手动删错。下面一步步来实操:

第一步:先明确规则

首先得统一质量优先级(行业通用排序,按从高到低):
WEB-DL > WEBRip > HDTV

  • WEB-DL是直接从流媒体平台提取的源文件,质量最高
  • WEBRip是对流媒体内容录屏转码的版本,次之
  • HDTV是从电视信号录制的版本,质量相对最低

同时先过滤常见视频格式,避免误处理非视频文件,比如.mkv, .mp4, .avi, .mov, .flv

第二步:提取剧集核心标识(关键是识别同一集)

要把同一集的不同版本归为一组,核心是从文件名里提取「剧集名称+季集号」的唯一标识。比如Game.of.Thrones.S01E01.WEB-DL.1080p.mkvGame.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

火山引擎 最新活动