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