In Powershell, what's the best way to join two tables into one?

杀马特。学长 韩版系。学妹 提交于 2019-11-26 00:15:55

问题


I\'m fairly new to Powershell, and am wondering if someone knows of any better way to accomplish the following example problem.

I have an array of mappings from IP address to host-name. This represents a list of active DHCP leases:

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

I have another array of mappings from MAC address to IP address. This represents a list of IP reservations:

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

For convenience, I was able to produce a third array of mappings from MAC address to IP address and host name using the following code. The idea is that $reservations should get a third field, \"Name\", which is populated whenever there\'s a matching \"IP\" field:

$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}}
    }
}

The desired output is something like this:

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

Is there any better way of doing this?


回答1:


Lee Holmes wrote up a blog post on a Join-Object function that does what you want. Too bad it isn't built into PowerShell yet.




回答2:


After 1.5 years, the cmdlet I had pasted in the original answer has undergone so many updates that it has become completely outdated. Therefore I have replaced the code and the ReadMe with a link to the latest version.

Join-Object

The Join-Object cmdlet can be download from PowerShell Gallery using the command:

Install-Script -Name Join

The Join package includes the Join-Object (alias Join) command and the following proxy commands:

  • InnerJoin-Object, alias InnerJoin (Join-Object -JoinType Inner)
    Only returns the joined objects
  • LeftJoin-Object, alias LeftJoin (Join-Object -JoinType Left)
    Returns the joined objects and the rest of the left objects
  • RightJoin-Object, alias RightJoin (Join-Object -JoinType Right)
    Returns the joined objects and the rest of the right objects
  • FullJoin-Object, alias FullJoin (Join-Object -JoinType Full)
    Returns the joined objects and the rest of the left and right objects
  • CrossJoin-Object, alias CrossJoin (Join-Object -JoinType Cross)
    Joins each left object to each right object
  • Update-Object, alias Update (Join-Object -JoinType Left -Merge = {RightOrLeft.$_})
    Updates the left object with the right object properties
  • Merge-Object, alias Merge (Join-Object -JoinType Full -Merge = RightOrLeft.$_})
    Updates the left object with the right object properties and inserts right if the values of the related property is not equal.

ReadMe

The full ReadMe (and source code) is available from GitHub: https://github.com/iRon7/Join-Object

Installation

After downloading (Install-Script -Name Join), the script can simply be invoked by dot sourcing:

. .\Join.ps1

You might also consider to convert the script to a PowerShell module by renaming it to a PowerShell module (.psm1) file and moving it to a one of the module folders defined in $env:PSModulePath. For more details see: How to Write a PowerShell Script Module.
Note: the Import-Module command is required to load the proxy commands.

Answer

To answer the actual example in the question:

$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

Examples

More examples can be found in the related Stackoverflow questions at:

  • Combining Multiple CSV Files
  • Combine two CSVs - Add CSV as another Column
  • CMD or Powershell command to combine (merge) corresponding lines from two files
  • Can I use SQL commands (such as join) on objects in powershell, without any SQL server/database involved?
  • CMD or Powershell command to combine (merge) corresponding lines from two files
  • Compare Two CSVs, match the columns on 2 or more Columns, export specific columns from both csvs with powershell
  • Merge two CSV files while adding new and overwriting existing entries
  • Merging two CSVs and then re-ordering columns on output
  • Merge two CSV files while adding new and overwriting existing entries
  • Efficiently merge large object datasets having multiple matching keys

And in the Join-Object test script.



来源:https://stackoverflow.com/questions/1848821/in-powershell-whats-the-best-way-to-join-two-tables-into-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!