PowerShell脚本:CSV文件夹双向中间名匹配及复制属性问题
PowerShell脚本优化:客户文件夹匹配与复制功能完善
问题概述
你当前的PowerShell脚本实现了从CSV读取客户信息匹配文件夹并导出结果的功能,但存在三个核心问题:
- 当CSV不含中间名但文件夹有中间名时,匹配失败;
- 无法区分完全匹配(中间名一致)和部分匹配(中间名存在差异或一方有一方无)的情况;
- 使用
Copy-Item无法保留文件夹的时间戳与权限。
解决方案
1. 修复中间名匹配逻辑
问题根源在于原正则绑定了CSV中的中间名变量,当CSV无中间名时会生成错误的匹配规则。我们调整为:不管CSV是否包含中间名,都允许文件夹名称中存在可选的中间名段,核心匹配姓氏、名字和案件编号即可。
关键调整:使用正则(?:_[^_]+)?表示可选的「下划线+任意非下划线字符」,兼容有/无中间名的文件夹结构。
2. 输出匹配状态
匹配后对比文件夹名称与CSV生成的「理想名称」:
- 若CSV有中间名,理想名称为
姓氏_名字_中间名_案件编号; - 若CSV无中间名,理想名称为
姓氏_名字_案件编号; - 一致则标记为
完全匹配,否则标记为部分匹配。
3. 修复Copy-Item属性保留问题
在PowerShell 5.1及以上版本,直接使用Copy-Item的参数实现属性保留:
-CopyTimestamp:保留创建、修改时间戳;-PreserveAuthorization:保留权限设置;- 配合
-Recurse和-Force实现递归覆盖。
若版本不支持,可替换为robocopy命令(参数/E /COPYALL复制所有属性)。
完整优化代码
# 请根据实际路径修改以下变量 $clients = "C:\Source\ClientFolders" $csv = "C:\Input\ClientCases.csv" $export = "C:\Output\MatchedFolders.csv" $targetDir = "C:\Target\CopiedFolders" # 获取所有源文件夹 $folders = Get-ChildItem $clients -Directory # 处理CSV并执行匹配、导出、复制 Import-Csv $csv | ForEach-Object { # 拆分姓氏和含中间名的全名 $last, $fullFirst = $_.Client -split ', *' $firstParts = $fullFirst -split ' ' $first = $firstParts[0] $middle = if ($firstParts.Count -gt 1) { $firstParts[1] } else { $null } # 提取案件编号的日期与数字段 if ($_.Case -match '\d{2}(\d{2})\d*(\d{5})') { $date = $matches[1] $number = $matches[2] $caseSuffix = "${date}-${number}" # 构建通用匹配正则 $matchPattern = "^${last}_${first}(?:_[^_]+)?_${caseSuffix}$" $matchingFolders = $folders | Where-Object { $_.Name -match $matchPattern } # 处理每个匹配的文件夹 foreach ($folder in $matchingFolders) { # 判断匹配类型 if ($middle) { $expectedName = "${last}_${first}_${middle}_${caseSuffix}" $matchStatus = if ($folder.Name -eq $expectedName) { "完全匹配" } else { "部分匹配" } } else { $expectedName = "${last}_${first}_${caseSuffix}" $matchStatus = if ($folder.Name -eq $expectedName) { "完全匹配" } else { "部分匹配" } } # 准备导出数据 $exportObj = [PSCustomObject]@{ Client = $_.Client CaseNumber = $_.Case FolderName = $folder.Name MatchStatus = $matchStatus SourcePath = $folder.FullName TargetPath = Join-Path $targetDir $folder.Name } # 导出到CSV(避免生成类型信息) $exportObj | Export-Csv -Path $export -Append -NoTypeInformation # 复制文件夹并保留属性 Copy-Item -Path $folder.FullName -Destination $exportObj.TargetPath -Recurse -Force -CopyTimestamp -PreserveAuthorization # 若PowerShell版本过低,替换为以下robocopy命令: # robocopy $folder.FullName $exportObj.TargetPath /E /COPYALL /R:3 /W:5 } } }
内容的提问来源于stack exchange,提问作者firebolt126
相关产品推荐
相关产品推荐

