如何使用PowerShell比对两个CSV文件FullPath列的内容差异
PowerShell实现两个CSV按FullPath列查找差集
原脚本问题
你的核心逻辑方向正确,但存在两个会导致比对失效的问题:
Select-Object "FullPath"返回的是携带FullPath属性的自定义对象集合,不是纯路径字符串集合,-notin运算符做匹配时是拿字符串和对象做比对,永远无法命中相同值,最终会导出SASSO1中所有符合条件的记录- 原代码中
select "FullPath"存在引号未闭合的语法问题,运行时会报错
基础可用实现(适合小体量CSV文件)
直接展开属性拿到纯字符串数组做比对,代码如下:
# 导入SASSO1.csv,筛选SourceType为file的记录,提取FullPath纯字符串集合 $data1 = Import-Csv "SASSO1.csv" | Where-Object { $_.SourceType -eq "file" } | Select-Object -ExpandProperty FullPath # 导入SASSO2.csv,同上处理得到比对基准的路径集合 $data2 = Import-Csv "SASSO2.csv" | Where-Object { $_.SourceType -eq "file" } | Select-Object -ExpandProperty FullPath # 筛选SASSO1有、SASSO2没有的路径,包装为带列名的对象后导出 $data1 | Where-Object { $_ -notin $data2 } | ForEach-Object { [PSCustomObject]@{ FullPath = $_ } } | Export-Csv "RISULTATO.csv" -NoTypeInformation -Encoding UTF8
补充说明
-ExpandProperty参数的作用是直接提取指定属性的值,返回对应类型的数组,而非保留对象外壳- 导出前重新包装为带
FullPath属性的对象,是为了让导出的CSV保留正确列名,方便后续使用 - 加上
-Encoding UTF8参数可以避免中文路径出现乱码 - Windows系统路径默认不区分大小写,如果需要忽略大小写做比对,可以把判断条件替换为
Where-Object { $data2 -inotcontains $_ }
大体量CSV优化实现
如果两个CSV文件行数过万,用数组直接-notin比对的性能会很差,可以用哈希集合优化比对速度:
# 初始化大小写不敏感的字符串哈希集合,存SASSO2的路径 $pathSet = [System.Collections.Generic.HashSet[string]]::new( [string[]](Import-Csv "SASSO2.csv" | Where-Object { $_.SourceType -eq "file" } | Select-Object -ExpandProperty FullPath), [System.StringComparer]::OrdinalIgnoreCase ) # 边读SASSO1边比对,不需要把所有数据加载到内存后再处理 Import-Csv "SASSO1.csv" | Where-Object { $_.SourceType -eq "file" -and -not $pathSet.Contains($_.FullPath) } | Select-Object FullPath | Export-Csv "RISULTATO.csv" -NoTypeInformation -Encoding UTF8
这个版本十万行级别的CSV比对也能在秒级完成,内存占用也更低。
内容的提问来源于stack exchange,提问作者Sunflower
相关产品推荐
相关产品推荐

