Powershell 比较对象从双方选择结果

Powershell 比较对象从双方选择结果

我已经阅读了许多比较两个对象、列表、数组等的例子。我似乎找不到或无法做到的是,在比较对象并找出哪一个相等之后,输出两个对象的一些属性

$sourceFiles | % { Compare-Object $_ $destFiles -IncludeEqual -ExcludeDifferent -Property Name}

这提供了预期的结果(即):

Name                                                SideIndicator                                                                              
----                                                -------------    
log4net.dll                                         ==                                                                                         
Ninject.dll                                         ==                                                                                         
Ninject.Extensions.Wcf.dll                          ==  

然后我怎样才能回到列表并输出类似这样的内容(我只能使用 $_ 对第一个列表执行此操作,但我不知道如何获取目标列表属性:

Name                                                Path1                            Path2                                                                              
----                                                -------------                    ---------------   
log4net.dll                                         C:\test\                         \\server\test                                                                                        
Ninject.dll                                         C:\test\                         \\server\test                                                                                  
Ninject.Extensions.Wcf.dll                          C:\test\                         \\server\test

我有类似的东西:

$source | ForEach-Object {
   $c = Compare-Object $_.Name $dest.Name -IncludeEqual -ExcludeDifferent
   if ($c.SideIndicator.ToString() -eq "=="){
     $_ | Select-Object Name, DirectoryName
   }
}

但输出仅针对比较 ($source) 第一侧的对象。我如何将此输出与第二个列表 ($dest) 关联?

答案1

您必须[PSCustomObject]使用名称构建一个从 $sourceFiles 和 $destFiles 中选择目录。

没有必要在 $sourceFiles 上使用 ForEach,直接比较变量即可。

$SourceFiles = Get-ChildItem 'C:\bat\' -File
$destFiles   = Get-ChildItem 'K:\Bat\' -File
Compare-Object $sourceFiles $destFiles -IncludeEqual -ExcludeDifferent -Property Name|
  ForEach-Object {
    [PSCustomObject]@{
      Name  = $_.Name
      Path1 = ($SourceFiles | Where-Object Name -eq $_.Name).Directory
      Path2 = ($destFiles   | Where-Object Name -eq $_.Name).Directory
    }
  }

示例输出:

Name              Path1  Path2
----              -----  -----
Arp-Scan.cmd      C:\bat K:\Bat
Arp-Scan.Log      C:\bat K:\Bat
BatchLib.cmd      C:\bat K:\Bat
BatchLib.INC      C:\bat K:\Bat

如果您知道 $sourceFiles/$destFiles 来自何处,并且它们不是以递归方式构建的,则Path1/Path2是静态的,因此上述脚本在我看来是矫枉过正。

否则您应该详细说明$sourceFiles/$destFiles的来源。

答案2

更紧凑一点:

$SourceFiles = Get-ChildItem 'C:\bat\' -File
$DestFiles   = Get-ChildItem 'K:\Bat\' -File
Compare-Object $SourceFiles $DestFiles -IncludeEqual -ExcludeDifferent -Property Name | Select-Object Name, @{n="Path1";e={$x=$_;($SourceFiles | Where-Object {$_.Name -eq $x.Name}.Directory)}}, @{n="Path2";e={$y=$_;($destFiles | Where-Object {$_.Name -eq $y.Name}.Directory)}}

相关内容