格式化比较对象输出

Formatting Compare-Object Ouput

大家好,早上好。

我只是想看看是否可以将 Compare-Object 的输出格式化为 pscustomobject。 我查看了以下类似的问题:

...但是,我似乎不明白它的概念。我不想问已经回答过的与此相关的问题,但是我有点困惑。第三个 link 是我唯一开始理解的一个,但仍然迷失在酱汁中。

只是想根据 SideIndicator return 属性.

分离输出
$Reference = Get-Content "C:\Users\Abe\Desktop\onj1.txt"
$Difference = Get-Content "C:\Users\Abe\Desktop\onj2.txt"


Compare-Object -ReferenceObject $Reference -DifferenceObject $Difference -IncludeEqual | Tee-Object -Variable CompareObject | Out-Null
$compareObject | Foreach { 
$ONJ1 = $_.SideIndicator -eq "<=" | Select $_.InputObject
$ONJ2 = $_.SideIndicator -eq "=>" | Select $_.InputObject
$Both = $_.SideIndicator -eq "==" | Select $_.inputobject

    [pscustomobject]@{
        ONJ1 = $ONJ1
        ONJ2 = $ONJ2
        Both = $Both
                }
        } 

不幸的是,所有 3 列 return 相同的输出,我假设它是因为我选择了 InputObject 属性 但是,它抓住了它们。

编辑:正如 Zett42

所解释的
$Reference = Get-Content "C:\Users\Abe\Desktop\onj1.txt"
$Difference = Get-Content "C:\Users\Abe\Desktop\onj2.txt"


Compare-Object -ReferenceObject $Reference -DifferenceObject $Difference -IncludeEqual | Tee-Object -Variable CompareObject | Out-Null

$null = [array]$ONJ1 = $compareObject | Where-Object {$_.SideIndicator -eq "<="} | Select-Object -ExpandProperty InputObject
$null = [array]$ONJ2 = $compareObject | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject
$null = [array]$Both = $compareObject | Where-Object {$_.SideIndicator -eq "=="} | Select-Object -ExpandProperty InputObject


For($i=0; $i -lt ($ONJ1.Count + $ONJ2.Count + $Both.Count); $i++){
    [pscustomobject]@{
        ONJ1 = $ONJ1[$i]
        ONJ2 = $ONJ2[$i]
        Both = $Both[$i]
                }
        } 

您获取的是格式化的输出字符串,而不是来自 Compare-Object 的实际数据。格式化输出将很难处理,因为它只是非结构化字符串。将 Compare-Object 的直接输出存储到变量中,而不通过管道传输到其他 cmdlet。然后你根据这些数据做进一步的处理。

$reference = 'foo', 'bar', 'baz', 'bim'
$difference = 'bim', 'fop', 'bar'

$compareObject = Compare-Object -ReferenceObject $Reference -DifferenceObject $Difference -IncludeEqual 

然后根据SideIndicator分离结果:

[array] $left  = $compareObject | Where-Object SideIndicator -eq '<=' | 
                                  Select-Object -ExpandProperty InputObject
[array] $right = $compareObject | Where-Object SideIndicator -eq '=>' | 
                                  Select-Object -ExpandProperty InputObject
[array] $both  = $compareObject | Where-Object SideIndicator -eq '==' |
                                  Select-Object -ExpandProperty InputObject

变量 $left 是一个数组,只包含 $Reference 中的项目,$right 只包含 $Difference$both 中的项目显然包含 $Reference$Difference.

中的项目

注意:我已将变量的类型明确设置为 [array],因此我们可以将单个元素输出视为与多个元素相同。将索引运算符应用于单个字符串将 select 单个 字符 ,而将索引运算符应用于 数组 字符串将输出单个 字符串 。通过将变量类型显式设置为 [array],我们无需额外代码即可处理这两种情况。

现在我们可以根据分离出来的结果做进一步的处理,e。 G。将它们填充到 [PSCustomObject]:

的单个数组中
# Determine the total number of rows we need. -1 to make it a valid array index.
$maxIndex = ( $left.Count, $right.Count, $both.Count | Measure-Object -Maximum ).Maximum - 1

foreach( $i in 0..$maxIndex ) {
    [pscustomobject]@{
        ONJ1 = if( $i -lt $left.Count )  { $left[ $i ] }  else { $null }
        ONJ2 = if( $i -lt $right.Count ) { $right[ $i ] } else { $null }
        Both = if( $i -lt $both.Count )  { $both[ $i ] }  else { $null }
    }
}

赋值右侧的 if/else 称为 conditional assignment(又名三元运算符)。由于每个数组 $left$right$both 可能具有不同的大小(小于 $maxIndex),我们需要确保不要“过冲”并使用无效的索引.

实际上只有在使用严格模式 >= v3.0(例如 Set-StrictMode -Version 3.0)时才需要这样做,在这种情况下,指定无效数组索引时会出现致命的“索引越界”错误。如果没有严格模式,您可以在不检查索引的情况下编写 ONJ1 = $left[ $i ]。就个人而言,我更愿意知道我的索引总是正确的,而不是依赖编程语言默默地“修复”我的错误。

输出:

ONJ1 ONJ2 Both
---- ---- ----
foo  fop  bar
baz       bim

不确定您期望的格式化输出,但也许是这样的?

onj1.txt

Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor.

onj2.txt

Lorem ipsum dolor sit amet, 
sed do eiusmod tempor.
$Reference = Get-Content "C:\Users\Abe\Desktop\onj1.txt"
$Difference = Get-Content "C:\Users\Abe\Desktop\onj2.txt"

$compare = Compare-Object -ReferenceObject $Reference -DifferenceObject $Difference -IncludeEqual

[PsCustomObject]@{
    ONJ1 = ($compare | Where-Object {$_.SideIndicator -eq "<="}).InputObject -join [environment]::NewLine
    ONJ2 = ($compare | Where-Object {$_.SideIndicator -eq "=>"}).InputObject -join [environment]::NewLine
    Both = ($compare | Where-Object {$_.SideIndicator -eq "=="}).InputObject -join [environment]::NewLine
} | Format-Table -Wrap

输出:

ONJ1                                                      ONJ2                         Both                  
----                                                      ----                         ----                  
Lorem ipsum dolor sit amet,                               Lorem ipsum dolor sit amet,  sed do eiusmod tempor.
consectetur adipiscing elit,