如何解决PowerShell:比较2个大型CSV文件以查找其中一个不存在的用户
我有2个CSV文件,每个都有10,000个用户。我需要计算有多少用户出现在csv1中而不是csv2中。目前,我有下面的代码。但是我知道这可能是非常低效的,因为它可能会遍历多达10,000个用户10,000次。该代码永远需要运行,我敢肯定必须有一种更有效的方法。感谢任何帮助或建议,我对Powershell还是陌生的
foreach ($csv1User in $csv1) {
$found = $false
foreach ($csv2User in $csv2) {
if ($csv1User.identifier -eq $csv2User.identifier)
{
$found = $true
break
}
}
if ($found -ne $true){
$count++
}
}
解决方法
如果将嵌套循环替换为2个HashSet,则将有两种方法来计算两者之间的异常:
使用handle.exe
通过HashSet<T>.SymmetricExceptWith()
函数,我们可以计算两个集合中都存在但两个集合中都不存在的术语子集:
SymmetricExceptWith()
使用集合来跟踪重复项
类似地,我们可以使用哈希集来跟踪至少观察过一次的术语,以及多次观察过的术语:
# Create hashset from one list
$userIDs = [System.Collections.Generic.HashSet[string]]::new([string[]]$csv1.identifier)
# Pass the other list to `SymmetricExceptWith`
$userIDs.SymmetricExceptWith([string[]]$csv2.identifier)
# Now we have an efficient filter!
$relevantRecords = @($csv1;$csv2) |Where-Object { $userIDs.Contains($_.identifier) } |Sort-Object -Unique identifier
使用哈希表作为分组构造
您还可以使用字典类型(例如# Create sets for tracking
$seenOnce = [System.Collections.Generic.HashSet[string]]::new()
$seenTwice = [System.Collections.Generic.HashSet[string]]::new()
# Loop through whole superset of records
foreach($record in @($csv1;$csv2)){
# Always attempt to add to the $seenOnce set
if(!$seenOnce.Add($record.identifier)){
# We've already seen this identifier once,add it to $seenTwice
[void]$seenTwice.Add($record.identifier)
}
}
# Just like the previous example,we now have an efficient filter!
$relevantRecords = @($csv1;$csv2) |Where-Object { $seenOnce.Contains($_.identifier) -and -not $seenTwice.Contains($_.identifier) } |Sort-Object -Unique identifier
)根据两个csv文件的标识符对记录进行分组,然后根据每个字典条目中的记录值数量进行过滤:
[hashtable]
,
如果您只是在寻找数量,那应该会更快。
$csv2 = Import-Csv $csvfile2
Import-Csv $csvfile1 |
Where-Object identifier -in $csv2.identifier |
Measure-Object | Select-Object -ExpandProperty Count
这是一个小例子
$csvfile1 = New-TemporaryFile
$csvfile2 = New-TemporaryFile
@'
identifier
bob
sally
john
sue
'@ | Set-Content $csvfile1 -Encoding UTF8
@'
identifier
bill
sally
john
stan
'@ | Set-Content $csvfile2 -Encoding UTF8
$csv2 = Import-Csv $csvfile2
Import-Csv $csvfile1 |
Where-Object identifier -in $csv2.identifier |
Measure-Object | Select-Object -ExpandProperty Count
输出很简单
2
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。