在 PowerShell 中,将两个表合并为一个表的最佳方法是什么?

2024-05-12

我对 PowerShell 相当陌生,想知道是否有人知道解决以下示例问题的更好方法。

我有一组从 IP 地址到主机名的映射。这表示活动 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 地址的映射数组。这代表 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 地址和主机名的第三个映射数组。这个想法是$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

有更好的方法吗?


1.5 年后,我在原始答案中粘贴的 cmdlet 经历了多次更新,以至于它已经完全过时了。因此我更换了代码和自述文件 https://github.com/iRon7/Join-Object并附有最新版本的链接。

连接对象 https://www.powershellgallery.com/packages/JoinModule

根据两个对象列表之间的相关属性组合它们。

描述
组合一个或多个对象的属性。它创建一个可以保存为新对象或按原样使用的集合。对象连接是一种通过使用每个对象列表中公共的值来组合来自一个(自连接)或多个对象列表的属性的方法。

主要特点

  • 直观、惯用的 PowerShell 语法
  • 类似 SQL 的连接功能
  • 智能财产合并
  • 用于更新、合并和特定连接类型的预定义连接命令
  • 为(左)输入对象和输出对象定义良好的管道(正确使用时保留内存)
  • 在大型对象列表上执行速度大约是 Compare-Object 的两倍
  • 支持(自定义)对象、数据表和字典(例如哈希表)作为输入
  • 智能属性和计算属性表达式
  • 自定义关系表达式
  • 安装方便(点采购)
  • 支持 PowerShell for Windows (5.1) 和 PowerShell Core

Join-Object cmdlet 显示以下代理命令及其自己的 (-JoinType and -Property) 默认值:

  • InnerJoin-Object (Alias InnerJoin or Join),组合相关对象
  • LeftJoin-Object (Alias LeftJoin),合并相关对象并添加剩余的左侧对象
  • RightJoin-Object (Alias RightJoin),组合相关对象并添加其余正确的对象
  • FullJoin-Object (Alias FullJoin),合并相关对象并添加其余左右对象
  • CrossJoin-Object (Alias CrossJoin),将每个左侧对象与每个右侧对象组合
  • Update-Object (Alias Update),用相关的右对象更新左对象
  • Merge-Object (Alias Merge),用相关的右对象更新左对象,并添加其余新的(不相关的)右对象

ReadMe https://github.com/iRon7/Join-Object

完整的自述文件(和源代码)可从 GitHub 获取:https://github.com/iRon7/Join-Object https://github.com/iRon7/Join-Object

安装

这个有两个版本Join-Objectcmdlet(两个版本提供相同的功能):

  • 加入模块 https://www.powershellgallery.com/packages/JoinModule
Install-Module -Name JoinModule
  • 加入脚本 https://www.powershellgallery.com/packages/Join
Install-Script -Name Join

(或重命名Join.psm1模块到一个Join.ps1脚本文件)
并通过调用脚本点源 https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scripts?view=powershell-6#script-scope-and-dot-sourcing:

. .\Join.ps1

Answer

回答问题中的实际示例:

$reservations |LeftJoin $leases -On IP

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

表现

关于绩效衡量的一点说明:
PowerShell 管道旨在stream对象(节省内存),这意味着两个列表输入对象通常不是(不应该)驻留在记忆中。通常它们是从其他地方(即远程服务器或磁盘)检索的。还,输出通常matters where linq https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/解决方案速度很快,但很容易让您在得出结论时陷入困境,因为linq字面上地defers执行(惰性评估 https://en.wikipedia.org/wiki/Lazy_evaluation), 也可以看看:从数组的属性获取唯一索引项的最快方法 https://stackoverflow.com/a/59437162/1701026.
换句话说,如果涉及(测量)PowerShell 的性能,重要的是要关注完整的端到端解决方案,这更有可能看起来像:

 import-csv .\reservations.csv |LeftJoin (import-csv .\leases.csv) -On IP |Export-Csv .\results.csv

(1) Note: unfortunately, there is no easy way to build two parallel input streams (see: #15206 Deferred input pipelines https://github.com/PowerShell/PowerShell/issues/15206)

(更多)示例

更多示例可以在相关的 Stack Overflow 问题中找到:

  • 合并多个 CSV 文件 https://stackoverflow.com/a/54855458/1701026
  • CMD 或 Powershell 命令组合(合并)两个文件中的相应行 https://stackoverflow.com/a/54607741/1701026
  • 我可以在 powershell 中的对象上使用 SQL 命令(例如 join),而不涉及任何 SQL 服务器/数据库吗? https://stackoverflow.com/a/55431393/1701026
  • Powershell 匹配属性,然后有选择地组合对象以创建第三个 https://stackoverflow.com/a/54855647/1701026
  • 比较两个 CSV,匹配 2 个或更多列上的列,使用 powershell 从两个 CSV 中导出特定列 https://stackoverflow.com/a/52235645/1701026
  • 合并两个 CSV 文件,同时添加新条目并覆盖现有条目 https://stackoverflow.com/a/54949056/1701026
  • 合并两个 CSV,然后对输出中的列重新排序 https://stackoverflow.com/a/54981257/1701026
  • 有效合并具有多个匹配键的大型对象数据集 https://stackoverflow.com/a/55543321/1701026
  • 如何比较两个 CSV 文件并输出其中一个文件中但不在两个文件中的行 https://stackoverflow.com/a/72012355/1701026
  • 如何使用 SQL LIKE 语法在 Powershell 中连接两个 CSV 文件 https://stackoverflow.com/a/73712540/1701026

并排连接示例

  • 合并两个 CSV - 将 CSV 添加为另一列 https://stackoverflow.com/a/55431240/1701026
  • 是否有相当于的 PowerShellpaste(即水平文件串联)? https://stackoverflow.com/a/68070763/1701026
  • 如何将3个循环合并并导出到一张表中 https://stackoverflow.com/a/74812558/1701026
  • 在powershell中将两个数组对象合并为一个数组对象 https://stackoverflow.com/q/75331465/1701026
  • 在 PowerShell 中将 XML 转换为 CSV 时,是否有办法将水平格式的 CSV 输出转换为垂直格式? https://stackoverflow.com/a/76330651/1701026
  • 如何将此 Json 数据作为平面对象而不是嵌套对象导入 https://stackoverflow.com/a/77022611/1701026

并且在连接对象测试脚本 https://github.com/iRon7/Join-Object/blob/master/Tests/Join-Object.Tests.ps1.

Please give a ???? if you support the proposal to Add a Join-Object cmdlet to the standard PowerShell equipment (#14994) https://github.com/PowerShell/PowerShell/issues/14994

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PowerShell 中,将两个表合并为一个表的最佳方法是什么? 的相关文章

随机推荐

  • 为 Eclipse 安装 Mercurial 插件时出错

    我刚刚为 Eclipse 安装了一个 Mercurial 插件 安装过程很顺利 但是安装后 当我重新启动 eclipse 时 显示错误 错误说 发生了多个 Mercurial 错误 请检查错误日志视图以获取详细信息 命令行 hg y deb
  • Twilio webRTC 通话在 10 分钟后中断

    使用 Twilio js 使用 webRTC 录制通话 工作正常 但在 10 分钟时 完全正确 电话挂断 TwiML 上的最大记录时间设置为 7200 秒 浏览器的控制台显示 Twilio PeerConnection signalingS
  • 让按钮更容易点击

    我有一个按钮 在某些手机上由于尺寸太大而很难点击 但让它变大会破坏布局 可以向视图解释它有一个比其可见区域更大的 点击框 吗 不确定这是否有帮助 如果您使用没有背景的 ImageButton 并设置 Padding 值 您的按钮将具有更大的
  • 如何在 Bootstrap 4 中隐藏和替换 navbar-toggler-icon?

    如何隐藏和替换 Bootstrap 4 中的导航栏切换图标 现在 下面的代码只是将 X 放在汉堡菜单下方
  • 是否可以共享 Symfony2 安装(一台服务器上的多个网站 [域])

    我想在一个根 服务器 下托管多个基于 Symfony2 的网站 是否可以共享 symfony 自己的文件 供应商等 有人知道教程吗 管理起来困难吗 AFAIK Symfony 安装大约有 600MB 我不想以冗余方式保存它 我看起来确实有可
  • ModuleNotFoundError:没有名为“pdfminer.high_level”的模块

    我在 pycharm 中从事项目 我想使用 pdfminer 将 pdf 文件转换为文本文件 我的问题是 当我运行该应用程序时 它无法工作 并且显示此错误消息 ModuleNotFoundError 没有名为 pdfminer high l
  • JS - 不可破坏空间的转换   [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在从 HTML 元素中读出文本并
  • 确保 config.h 包含一次

    我有一个库项目 正在使用 Linux 中的 autotools 套件移植到该项目 我对自动工具很陌生 本周 我已经了解了其操作的基础知识 我有一个关于如何保留内容的问题config h免遭重新定义 我惊讶地发现生成的config h文件也没
  • Heroku:无法通过 Bundler 安装 gem

    我尝试使用以下命令将我的 Rails 应用程序推送到 Herokugit push heroku master f命令 我得到这个 Total 0 delta 0 reused 0 delta 0 remote Compressing so
  • 如何在部署作业期间设置 XML 转换的环境名称?

    好的 伙计们 给 Azure多级管道尝试一下 但不太幸运地使用部署作业进行 xml 转换 Update 这没有使用 Azure DevOps 中的经典部署 发布 UI 到目前为止我所做的 从构建过程中删除转换 尝试一次构建并随处部署 通过删
  • 错误:“uint16_t”未声明? [复制]

    这个问题在这里已经有答案了 我有代码 include
  • 身份验证和用户任务

    我正在考虑开发一个具有明确定义域的系统 主要基于网络 域的一部分包括像这样的实体Diary Booking Customer etc 不过我创建了另一个名为User其目的仅用于身份验证和授权 污染Customer具有特定于身份验证的数据的实
  • 从架构中删除表 - Rails

    我想删除架构中的一个表 我在第一次启动项目时创建了数据库并希望删除该表 这样做的最佳方法是什么 I tried rails g migration drop table installs但这只会创建一个空迁移 Schema create t
  • 匹配同一端口上不同路径的 Istio 虚拟服务路由

    我想知道如何在同一端口上匹配 gRPC 路由 以下是我希望通过 VirtualService 实现的目标的示例 apiVersion networking istio io v1alpha3 kind VirtualService meta
  • 使用 System.Threading.Tasks.Task 而不是 Stream

    我在以前版本的 WCF Web API 上使用了如下方法 grab the posted stream Stream stream request Content ContentReadStream write it to using Fi
  • opencv 2.3.* 读取不工作

    我无法让 imread 工作 与这个人有同样的问题 OpenCV imwrite 2 2 在 Windows 7 上导致异常 并显示消息 OpenCV 错误 未指定错误 无法找到指定扩展名的编写器 https stackoverflow c
  • 如何在使用 Active Storage 上传之前调整图像大小(与 AWS 链接)

    我尝试将 Active Storage 与 Amazon Web Services 结合使用 而不是 Carrierwave 和 Cloudinary 使用 Carrierwave 我有一些功能可以在通过上传器控制器上传之前调整图像大小 但
  • execlp 多个“程序”

    我想运行类似的东西 cat file tar base64 myprogram c base64 d tar zvt I use execlp运行该进程 当我尝试运行类似的东西时cat它有效 但如果我尝试运行base64 d tar zvt
  • 匹配不包含超过 x 个连续字符的字符串的正则表达式是什么

    我想要匹配不包含连续 3 个以上重复的相同字符的字符串 所以 abaaaa 不匹配 abawdasd 比赛 abbbbasda 不匹配 巴巴巴巴 比赛 是的 对包含连续字符进行正则表达式匹配 然后在代码中对其进行否定会更容易 更简洁 然而
  • 在 PowerShell 中,将两个表合并为一个表的最佳方法是什么?

    我对 PowerShell 相当陌生 想知道是否有人知道解决以下示例问题的更好方法 我有一组从 IP 地址到主机名的映射 这表示活动 DHCP 租约的列表 PS H gt leases IP Name 192 168 1 1 Apple 1