【问题标题】:Sorting Results of If Statement Without Using Compare-Object不使用比较对象对 If 语句的结果进行排序
【发布时间】:2019-05-22 01:03:26
【问题描述】:

我正在尝试创建一个排序函数来将我的对象排序到三个不同的列表中。每个对象都包含服务器的名称(除其他外),位于“名称”列下。我正在尝试创建三个列表。一种包含出现在两个对象上的服务器名称,一种包含仅出现在 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 时,它会完全按照我的预期输出三个列表。我的逻辑错了吗?

【问题讨论】:

  • 如果可以分享$txtFile$csvFile的示例内容就好了。您是否尝试在编辑器中进行调试?

标签: arrays powershell sorting compare


【解决方案1】:

您可以自己遍历列表,但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

【讨论】:

  • 感谢您的回复。使用“Compare-Object”的最大问题是完成后我仍然需要使用每个文件中的所有列。所以一旦比较完成,我仍然需要能够说“If ($grouped.sideIndicator -eq "==") { $finalName += $csvFile.Name, $finalOS += $csvFile.OS, $finalTarget += $csvFile.'Target Destination'}。如果我使用 Compare-Object,我将无法再使用这些字段
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2023-03-03
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多