我正在尝试创建一个排序函数,将我的对象分类为三个不同的列表。每个对象都包含服务器的名称(以及其他内容),在"名称"列下。我正在尝试创建三个列表。一个包含出现在两个对象上的服务器名称,一个包含仅出现在 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
时,它会完全按照我的预期输出三个列表。我的逻辑在这里有错吗?
您可以自己遍历列表,但Compare-Object
已经完成了您需要的所有迭代和比较。您只需要在之后过滤结果即可。这很容易通过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
在我对你上一个问题的回答的基础上:
## Q:Test20181221SO_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