在 PowerShell 中比较多个 CSV 列和 return 完整数据
Compare multiple CSV columns and return complete data from both in PowerShell
我有两个包含数据的电子表格,我想比较这些数据以突出显示匹配和不匹配的数据,其中一些 "gotchas" - 一些列我想忽略以进行比较(分数、测试名称),其他我想要包括(文件名和哈希),我想通过双方(所以即使它不匹配,我也想做一个 "full outer" 查询)。这是我的示例数据:
CSV1(来源):
FileName, ServerName, TestName, Hash, Score
C:\temp, ServerA, TestA, 12345, 100
C:\temp1, ServerA, TestA, 12345, 100
C:\temp2, ServerA, TestA, 12345, 5
C:\temp3, ServerA, TestA, 8888, 100
C:\temp5, serverA, TestB, 9999, 100
CSV2(比较目标):
FileName, ServerName, TestName, Hash, Score
C:\temp, ServerB, TestA, 12345, 100
C:\temp1, ServerB, TestA, 5555, 100
C:\temp3, ServerB, TestA, 8888, 100
C:\temp5, ServerB, TestB, 9999, 100
C:\temp7, ServerB, TestB, 5678, 22
我想看看文件名和哈希值是否匹配 - 例如
C:\temp 和 C:\temp5 会匹配
和 return 所有带有侧边指示符的列 - 例如
输出 CSV
SourceFileName, SourceServer,DestinationServer, ..., Match, Score
C:\temp, ServerA, ServerB, True, 100
C:\temp3, ServerA, ServerB, True, 8888
C:\temp1, ServerA, ServerB, False, 100
C:\temp2, ServerA, N/A, False, 5
C:\temp7, N/A, ServerB, False, 22
我使用了 ForEach($record in $CSV1) 并检查了匹配的文件名,然后是哈希,但是它在处理大量数据时速度很慢(我怀疑是因为我的完整外部查询需要我用新的扩展我的哈希表所有列的成员)。
我认为 Compare-object 会很合适,但这似乎不允许我在 passthru 语句中包含双方,除非我遗漏了什么?
使用这个 Join-Object
:
$CSV1 | FullJoin $CSV2 -On FileName -Property @{
SourceFileName = {If ($Left.FileName) {$Left.FileName} Else {$Right.FileName}}
SourceServer = {$Left.ServerName}
DestinationServer = {$Right.ServerName}
Match = {$Left.Hash -eq $Right.Hash}
Score = {If ($Left.$_ -gt $Right.$_) {$Left.$_} Else {$Right.$_}}
} |Format-Table
Match DestinationServer Score SourceFileName SourceServer
----- ----------------- ----- -------------- ------------
True ServerB 100 C:\temp ServerA
False ServerB 100 C:\temp1 ServerA
False 5 C:\temp2 ServerA
True ServerB 100 C:\temp3 ServerA
True ServerB 100 C:\temp5 serverA
False ServerB 22 C:\temp7
我有两个包含数据的电子表格,我想比较这些数据以突出显示匹配和不匹配的数据,其中一些 "gotchas" - 一些列我想忽略以进行比较(分数、测试名称),其他我想要包括(文件名和哈希),我想通过双方(所以即使它不匹配,我也想做一个 "full outer" 查询)。这是我的示例数据:
CSV1(来源):
FileName, ServerName, TestName, Hash, Score
C:\temp, ServerA, TestA, 12345, 100
C:\temp1, ServerA, TestA, 12345, 100
C:\temp2, ServerA, TestA, 12345, 5
C:\temp3, ServerA, TestA, 8888, 100
C:\temp5, serverA, TestB, 9999, 100
CSV2(比较目标):
FileName, ServerName, TestName, Hash, Score
C:\temp, ServerB, TestA, 12345, 100
C:\temp1, ServerB, TestA, 5555, 100
C:\temp3, ServerB, TestA, 8888, 100
C:\temp5, ServerB, TestB, 9999, 100
C:\temp7, ServerB, TestB, 5678, 22
我想看看文件名和哈希值是否匹配 - 例如 C:\temp 和 C:\temp5 会匹配 和 return 所有带有侧边指示符的列 - 例如
输出 CSV
SourceFileName, SourceServer,DestinationServer, ..., Match, Score
C:\temp, ServerA, ServerB, True, 100
C:\temp3, ServerA, ServerB, True, 8888
C:\temp1, ServerA, ServerB, False, 100
C:\temp2, ServerA, N/A, False, 5
C:\temp7, N/A, ServerB, False, 22
我使用了 ForEach($record in $CSV1) 并检查了匹配的文件名,然后是哈希,但是它在处理大量数据时速度很慢(我怀疑是因为我的完整外部查询需要我用新的扩展我的哈希表所有列的成员)。
我认为 Compare-object 会很合适,但这似乎不允许我在 passthru 语句中包含双方,除非我遗漏了什么?
使用这个 Join-Object
:
$CSV1 | FullJoin $CSV2 -On FileName -Property @{
SourceFileName = {If ($Left.FileName) {$Left.FileName} Else {$Right.FileName}}
SourceServer = {$Left.ServerName}
DestinationServer = {$Right.ServerName}
Match = {$Left.Hash -eq $Right.Hash}
Score = {If ($Left.$_ -gt $Right.$_) {$Left.$_} Else {$Right.$_}}
} |Format-Table
Match DestinationServer Score SourceFileName SourceServer
----- ----------------- ----- -------------- ------------
True ServerB 100 C:\temp ServerA
False ServerB 100 C:\temp1 ServerA
False 5 C:\temp2 ServerA
True ServerB 100 C:\temp3 ServerA
True ServerB 100 C:\temp5 serverA
False ServerB 22 C:\temp7