我对PowerShell还是个新手,我想知道是否有人知道更好的方法来完成下面的示例问题。
我有一个从IP地址到主机名的Map数组。这表示一个活动DHCP租约列表:
PS H:\> $leases
IP Name
-- ----
192.168.1.1 Apple
192.168.1.2 Pear
192.168.1.3 Banana
192.168.1.99 FishyPC
我有另一个从MAC地址到IP地址的Map数组,它代表了一个IP预留列表:
PS H:\> $reservations
IP MAC
-- ---
192.168.1.1 001D606839C2
192.168.1.2 00E018782BE1
192.168.1.3 0022192AF09C
192.168.1.4 0013D4352A0D
为了方便起见,我使用下面的代码生成了从MAC地址到IP地址和主机名的第三个Map数组,其思想是$reservations
应该获得第三个字段“Name”,只要有匹配的“IP”字段,就会填充该字段:
$reservations = $reservations | foreach {
$res = $_
$match = $leases | where {$_.IP -eq $res.IP} | select -unique
if ($match -ne $NULL) {
"" | select @{n="IP";e={$res.IP}}, @{n="MAC";e={$res.MAC}}, @{n="Name";e={$match.Name}}
}
}
所需的输出如下所示:
PS H:\> $ideal
IP MAC Name
-- --- ----
192.168.1.1 001D606839C2 Apple
192.168.1.2 00E018782BE1 Pear
192.168.1.3 0022192AF09C Banana
192.168.1.4 0013D4352A0D
有没有更好的办法?
5条答案
按热度按时间nnsrf1az1#
1.5年后,我粘贴在原始答案中的cmdlet经历了如此多的更新,以至于它已经完全过时,因此我用指向最新版本的链接替换了code and the ReadMe。
∮ ∮ ∮ ∮
根据两个对象列表之间的相关特性合并它们。
组合一个或多个对象的属性。它创建一个集,该集可另存为新对象或按原样使用。对象联接是一种通过使用一个(自联接)或多个对象列表的公用值来组合这些对象列表的属性的方法。
Join-Object cmdlet显示以下代理命令及其各自的默认值(
-JoinType
和-Property
):InnerJoin-Object
(别名InnerJoin
或Join
),合并相关对象LeftJoin-Object
(AliasLeftJoin
),合并相关对象并添加左侧的其余对象RightJoin-Object
(AliasRightJoin
),合并相关对象并添加其余的右侧对象FullJoin-Object
(AliasFullJoin
),合并相关对象并添加左侧和右侧的其余对象CrossJoin-Object
(AliasCrossJoin
),将每个左侧对象与每个右侧对象合并Update-Object
(AliasUpdate
),使用相关的右侧对象更新左侧对象Merge-Object
(AliasMerge
),使用相关的右侧对象更新左侧对象,并添加其余的新(不相关)右侧对象∮ ∮ ∮ ∮
完整的自述文件(和源代码)可从GitHub获得:https://github.com/iRon7/Join-Object
安装
此
Join-Object
cmdlet有两个版本(两个版本提供相同的功能):(or将
Join.psm1
模块重命名为Join.ps1
脚本文件)并通过dot sourcing调用脚本:
答案
要回答问题中的实际示例:
性能
关于绩效衡量的一点说明:
PowerShell管道设计用于"流式传输"对象(这样可以保护内存),这意味着输入对象的两个¹列表通常都不是(不应)驻留在内存中。通常从其他位置检索它们(即远程服务器或磁盘)。另外,* * 输出通常很重要在
linq
解决方案速度快但可能容易使您在得出结论时措手不及的情况下,因为linq
确实 * 延迟 * 了执行(lazy evaluation),另请参见:fastest way to get a uniquely index item from the property of an array.换句话说,如果要在PowerShell中(测量)性能,必须查看完整的端到端解决方案**,该解决方案更可能类似于:
(1)注意:遗憾的是,没有简单的方法来构建***两个***并行输入流(参见:
#15206
Deferred input pipelines)(更多)示例
有关堆栈溢出问题的更多示例,请访问:
paste
(i.e., horizontal file concatenation)?而在Join-Object test script中。
如果您支持对Add a Join-Object cmdlet to the standard PowerShell equipment (
#14994
)的建议,请给出a👍 if you support the proposal to Add a Join-Object cmdlet to the standard PowerShell equipment (#14994
)pepwfjgg2#
这也可以使用我的模块Join-Object来完成
关于性能,我对100 k行的样本数据进行了测试:
1.由@js2010发布的哈希表示例运行时间为8秒。
Join-Object
由我运行在14秒。LeftJoin
by @iRon在1分50秒内运行hpxqektj3#
下面是一个使用哈希表的简单例子,对于大数组,这个方法会更快。
yh2wf1be4#
我发现合并两个Powershell对象的最简单方法是使用ConvertTo-Json和ConvertFrom-Json
结果:
再举一个例子,让我们制作一对对象:
输出:
可以在foreach中再次执行相同的操作:
输出:
vuv7lop35#
可以像这样使用脚本块