优化PowerShell文件检查脚本:匹配基名并展示对应版本
优化后的PowerShell函数实现
核心思路
- 一次性递归扫描目标文件夹,将文件按「基名-版本」格式拆分后存入哈希表,避免循环内重复扫描,大幅提升效率。
- 参数化文件夹路径和文件列表路径,让函数更通用。
- 按需求输出不同颜色的结果:青色显示匹配到的基名及对应版本,绿色显示完整匹配的文件(保留原脚本功能),红色显示缺失的文件。
完整函数代码
function Test-FilePresence { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$TargetFolder, [Parameter(Mandatory = $true)] [string]$FileListPath ) # 预加载目标文件夹所有文件,拆分基名和版本,存入哈希表(键:基名,值:版本数组) $fileIndex = @{} Get-ChildItem -Path $TargetFolder -Recurse -File | ForEach-Object { if ($_.BaseName -match '^([^-]+)-(\d+)$') { $baseName = $matches[1] $version = $matches[2] if (-not $fileIndex.ContainsKey($baseName)) { $fileIndex[$baseName] = @() } $fileIndex[$baseName] += $version # 去重,避免同一版本多次存储 $fileIndex[$baseName] = $fileIndex[$baseName] | Select-Object -Unique } } # 读取文件列表 $fileNames = Get-Content -Path $FileListPath Write-Host "目标文件夹: $TargetFolder" Write-Host "开始检查文件列表..." -ForegroundColor Cyan foreach ($name in $fileNames) { $name = $name.Trim() if ([string]::IsNullOrEmpty($name)) { continue } # 先检查是否是完整的「基名-版本」格式,匹配原脚本逻辑 $fullMatch = Get-ChildItem -Path $TargetFolder -Recurse -File | Where-Object { $_.BaseName -eq $name } if ($fullMatch) { Write-Host "FILE $name 存在" -ForegroundColor Green # 同时提取基名和版本输出青色信息 if ($name -match '^([^-]+)-(\d+)$') { Write-Host " 对应基名: $($matches[1]),版本: $($matches[2])" -ForegroundColor Cyan } continue } # 检查是否匹配基名(假设列表中可能直接写基名,如51713) if ($fileIndex.ContainsKey($name)) { $versions = $fileIndex[$name] -Join ', ' Write-Host "基名 $name 存在对应文件,版本: $versions" -ForegroundColor Cyan continue } # 既无完整匹配也无基名匹配,标记缺失 Write-Host "FILE $name 在文件夹中缺失" -ForegroundColor Red } }
使用示例
# 调用函数,指定目标文件夹和文件列表路径 Test-FilePresence -TargetFolder 'K:\dxf\dxf50000-60000' -FileListPath '.\files.txt'
优化点说明
- 效率提升:仅扫描目标文件夹一次,后续通过哈希表快速查找,避免原脚本中每次循环都递归扫描的性能浪费。
- 功能扩展:同时支持完整文件名匹配(保留原逻辑)和基名匹配,满足新增需求。
- 鲁棒性:跳过文件列表中的空行,对文件名格式做正则校验,避免无效匹配。
- 可读性:参数化设计让函数复用性更强,代码结构清晰,注释明确。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

