PowerShell比对CSV文件匹配值速度过慢,求性能优化方案
优化PowerShell CSV匹配脚本:从20分钟到几秒搞定
嘿,我太懂你这种崩溃感了——18条数据居然跑20分钟,这绝对是匹配逻辑的效率问题。咱们直接把核心问题揪出来:你原来的代码是在foreach循环里每次都用Where-Object遍历整个$fileContentMagic数组找匹配,这属于O(n²)的时间复杂度,数据量稍微大一点(哪怕你的$fileContentMagic实际条目不少),速度就会雪崩式下降。
下面给你一套优化方案,直接把效率拉满:
核心思路:用哈希表做快速查找
哈希表(PowerShell里的@{})的查找是常数时间O(1),我们先把$fileContentMagic里的匹配字段和对应的IGG值提前存入哈希表,之后遍历$fileContentIMM时直接查表就行,不用再反复遍历整个数组。
步骤1:预处理构建查找哈希表
先把$fileContentMagic转换成键值对结构,用Matricule+Nom+Prenom的组合作为唯一键(如果Matricule本身唯一,只用它就行,更简洁):
# 初始化哈希表 $magicLookup = @{} # 遍历$fileContentMagic,把匹配字段和IGG值存入哈希表 foreach ($magicItem in $fileContentMagic) { # 构建唯一键:先Trim掉字段的多余空格,避免因空格导致匹配失败 $matricule = $magicItem.Matricule.Trim() $nom = $magicItem.Nom.Trim() $prenom = $magicItem.Prenom.Trim() $key = "$matricule_$nom_$prenom" # 避免重复键覆盖(如果有重复条目,这里取第一个匹配的IGG,也可以改成取最后一个) if (-not $magicLookup.ContainsKey($key)) { $magicLookup[$key] = $magicItem.IGG } }
步骤2:快速匹配并提取数据
现在遍历$fileContentIMM时,直接从哈希表里取数据,不用再做全数组遍历:
# 存储匹配结果 $matchingResults = foreach ($item in $fileContentIMM) { try { # 同样处理字段空格,和哈希表的键保持一致 $matricule = $item.Matricule.Trim() $nom = $item.Nom.Trim() $prenom = $item.Prenom.Trim() $key = "$matricule_$nom_$prenom" # 直接查表,一秒找到匹配 if ($magicLookup.ContainsKey($key)) { # 输出需要的结果对象,可按需调整字段 [PSCustomObject]@{ Matricule = $matricule Nom = $nom Prenom = $prenom IGG = $magicLookup[$key] } } else { # 没有匹配到的情况,可自定义处理(比如标记未找到) [PSCustomObject]@{ Matricule = $matricule Nom = $nom Prenom = $prenom IGG = "未找到匹配" } } } catch { # 异常处理,输出错误信息方便排查 Write-Warning "处理条目 $matricule 时出错:$_" } } # 把结果导出到CSV(按需调整路径和编码) $matchingResults | Export-Csv -Path "匹配结果.csv" -NoTypeInformation -Encoding UTF8
额外优化建议
- 简化键的结构:如果
Matricule本身是唯一标识,直接用$magicLookup[$magicItem.Matricule.Trim()] = $magicItem.IGG就行,不用拼接Nom和Prenom,效率更高。 - 处理重复条目:如果
$fileContentMagic里有相同的Matricule+Nom+Prenom组合,你可以改成把IGG存为数组:$magicLookup[$key] += @($magicItem.IGG),后续按需处理。 - CSV读取优化:用
Import-Csv读取文件时,尽量指定正确的编码(比如-Encoding UTF8),避免字段乱码导致匹配失败。
这样改完之后,别说18条数据,哪怕是几千条数据,也能在几秒内搞定。
内容的提问来源于stack exchange,提问作者Nguyen kevin
相关产品推荐
相关产品推荐

