哈希表转换报错:ConvertFrom-StringData遇重复MD5项需去重
问题与解决方案
问题描述
参考示例编写脚本时,执行以下代码出现重复键错误:
$remotefilehash = ($remotefiles -replace '^[a-f0-9]{32}( )', '$0= ' -join "`n") | ConvertFrom-StringData
完整错误信息:
ConvertFrom-StringData : Data item '4826367e20469078693dced6dc642b96' in line '4826367e20469078693dced6dc642b96 = My Videos/Drone/DJI-FPV/DJI_0003.MP4' is already defined. At P:\scripts\code\pcloud_sync.ps1:66 char:86 + ... ace '^[a-f0-9]{32}( )', '$0= ' -join "`n") | ConvertFrom-StringData + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [ConvertFrom-StringData], PSInvalidOperationException + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand
需求说明:需要对存储MD5值与文件路径的remoteFiles列表/数组按MD5值去重,存在同一MD5对应不同文件路径的情况。
解决方案
ConvertFrom-StringData不允许键重复,因此不能用该方式处理。直接对remoteFiles数组按MD5分组处理即可,以下是几种实用方案:
方案1:保留每个MD5对应的第一个路径
# 假设remoteFiles每一行格式为 "MD5值 文件路径" $uniqueRemoteFiles = $remotefiles | Group-Object -Property { $_ -replace '^([a-f0-9]{32}).*', '$1' } | ForEach-Object { $_.Group[0] }
方案2:将同一MD5的所有路径合并为数组(保留全部路径)
$md5ToPaths = @{} foreach ($line in $remotefiles) { $md5 = $line -replace '^([a-f0-9]{32}).*', '$1' $path = $line -replace '^[a-f0-9]{32}\s+', '' if ($md5ToPaths.ContainsKey($md5)) { $md5ToPaths[$md5] += $path } else { $md5ToPaths[$md5] = @($path) } } # 输出结果示例 $md5ToPaths.GetEnumerator() | ForEach-Object { Write-Host "MD5: $($_.Key) 关联路径: $($_.Value -join ', ')" }
方案3:生成无重复MD5的哈希表(仅保留最后一个关联路径)
$md5Hash = @{} foreach ($line in $remotefiles) { # 按空格分割为MD5和路径两部分(兼容路径含空格的情况) $splitParts = $line -split '\s+', 2 if ($splitParts.Count -eq 2) { $md5Hash[$splitParts[0]] = $splitParts[1] } }
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

