我正在尝试创建一个排序功能,以将我的对象分为三个不同的列表。每个对象均在“名称”(Name)列下包含服务器的名称(除其他外)。我正在尝试创建三个列表。一种包含同时出现在两个对象上的服务器名称,一种包含仅出现在txtFile对象上的服务器名称,另一种包含仅出现在csvFile对象上的服务器名称。这是我到目前为止的内容:
If ($txtFile.Name -contains $csvFile.Name) {
$onBothLists += $csvFile.Name
}
ElseIf ($txtFile.Name -notcontains $csvFile.Name) {
$onlyOnTxtFile += $txtFile.Name
}
ElseIf ($csvFile.Name -notcontains $txtFile.Name) {
$onlyOnCsvFile += $csvFile.Name
}
我的问题是,运行此命令时,会填充$onBothLists
和$onlyOnTxtFile
,而不会填充$onlyOnCsvFile
。但是,当我为他们运行Compare-Object
时,它将输出三个列表,它们的显示与我期望的完全相同。我的逻辑错了吗?
答案 0 :(得分:2)
您可以自己遍历列表,但可以Compare-Object
already does all the iterating and comparison you need。您只需要随后过滤结果即可。 This is made easy by Group-Object
。
Compare-Object
返回一个对象列表,每个对象包含2个属性:原始对象(.InputObject
)和在(.SideIndicator
)中找到结果对象的指示符,该对象显示==
适用于两个物体,或火箭适用于方向<=
和=>
。
通过对侧指标进行分组并以[hashtable]
的形式给出分组结果,我们可以轻松地通过并排指标索引该表以获得所需的结果:
$list1 = echo serverA serverB serverC serverD serverE
$list2 = echo serverD serverE serverF serverG serverH
$grouped = Compare-Object -ReferenceObject $list1 -DifferenceObject $list2 -IncludeEqual |
Group-Object -Property SideIndicator -AsHashTable -AsString
# both
$grouped['=='].InputObject
# in list1
$grouped['<='].InputObject
# in list2
$grouped['=>'].InputObject
对于相同的对象,您可以执行以下操作:
Compare-Object -ReferenceObject $list1 -DifferenceObject $list2 -IncludeEqual -ExcludeDifferent
答案 1 :(得分:2)
以我对您的previous question的回答为基础:
## Q:\Test\2018\12\21\SO_53886784.ps1
$csvFile = Import-Csv .\sample.csv
$txtFile = Import-csv .\sample.txt -Header Name
$newCsv = Compare-Object -Ref $csvFile -Dif $txtFile -Property Name -IncludeEqual
$onBothLists = $newCsv | Where-Object SideIndicator -eq '==' | Select-Object -Expand Name
$onlyOnTxtFile = $newCsv | Where-Object SideIndicator -eq '=>' | Select-Object -Expand Name
$onlyOnCsvFile = $newCsv | Where-Object SideIndicator -eq '<=' | Select-Object -Expand Name
示例输出:
> $onBothLists
wddg9028
htew804
> $onlyOnTxtFile
test1234
> $onlyOnCsvFile
other321