简体   繁体   English

Powershell:尝试组合两个不使用相同列的数组

[英]Powershell: Trying to combine two arrays that don't use the same columns

I have two arrays imported from csv files, which from here on i will refer to as the master array and update array.我有两个从 csv 文件导入的数组,从这里开始我将它们称为主数组和更新数组。

The master array has three extra columns on the front, and three extra columnns on the back.主阵列在前面有三个额外的列,在后面有三个额外的列。

Each day i get a new update array that i need to do two things with.每天我都会得到一个新的更新数组,我需要用它做两件事。

A) Remove any rows on the master that do not appear in the update A) 删除 master 上没有出现在更新中的任何行

B) Add any rows that appear in the update but not the master to the master B) 将出现在更新中但未出现在 master 中的任何行添加到 master

I am still fairly new to powershell, and scripting in general(mostly self taught) and can't figure out how to approach this.我对 powershell 和一般的脚本编写(主要是自学)仍然相当陌生,并且无法弄清楚如何解决这个问题。 I know there's a compare-object command, so I can get a list of which rows match pretty easily, but I'm not sure how to combine them the way I want.我知道有一个 compare-object 命令,所以我可以很容易地得到哪些行匹配的列表,但我不确定如何按照我想要的方式组合它们。

Edit: The master array entries have this information:编辑:主阵列条目具有以下信息:

ef: true ef: 真的
ea: true ea:真的
rem: true雷姆:真的
accountname: example1账户名:example1
Enabled: True启用:真
PasswordLastSet: 01/08/2002 13:14:19密码上次设置:01/08/2002 13:14:19
whencreated: 01/08/2002 13:14:19创建时间:01/08/2002 13:14:19
Description:描述:
Owner Email: johnsmith@email.com业主邮箱:johnsmith@email.com
givenname: John姓名:约翰
sn: Smith SN:史密斯
manager: John Doe经理:John Doe
Level2: Person 1级别 2:人员 1
Level3: Person 2级别 3:人员 2
Level4: Person 3级别 4:第 3 个人

While the updates only have:虽然更新只有:

accountname: example1账户名:example1
Enabled: True启用:真
PasswordLastSet: 01/08/2002 13:14:19密码上次设置:01/08/2002 13:14:19
whencreated: 01/08/2002 13:14:19创建时间:01/08/2002 13:14:19
Description:描述:
Owner Email: johnsmith@email.com业主邮箱:johnsmith@email.com
givenname: John姓名:约翰
sn: Smith SN:史密斯
manager: John Doe经理:John Doe

Assuming the accountname column can be used as the unique key that ties the two arrays together, you could use something like the below script.假设 accountname 列可以用作将两个数组联系在一起的唯一键,您可以使用类似于以下脚本的内容。 It creates a third array and then overwrites the master array csv once completed.它创建第三个数组,然后在完成后覆盖主数组 csv。

$arrmaster = import-csv c:\temp\arrmaster.csv
$arrupdate = import-csv c:\temp\arrupdate.csv
$arrworking = @()

foreach ($rowupdate in $arrupdate){
    $rowmaster = @($arrmaster | where {$_.accountname -eq $rowupdate.accountname})
    if ($rowmaster.Count -lt 1){
        Write-Debug "Could not find record for $($row.accountname)"
    } 
    if ($rowmaster.Count -gt 1){
        Write-Debug "Found duplicate records for $($row.accountname)"
    }
    if ($rowmaster.Count -eq 1){
        $rowworking = "" | select ef,ea,rem,accountname,Enabled,PasswordLastSet,whencreated,Description,"Owner Email",givenname,sn,manager,Level2,Level3,Level4
        $rowworking.ef              = $rowmaster.ef
        $rowworking.ea              = $rowmaster.ea
        $rowworking.rem             = $rowmaster.rem
        $rowworking.accountname     = $rowupdate.accountname
        $rowworking.Enabled         = $rowupdate.Enabled
        $rowworking.PasswordLastSet = $rowupdate.PasswordLastSet
        $rowworking.whencreated     = $rowupdate.whencreated
        $rowworking.Description     = $rowupdate.Description
        $rowworking."Owner Email"   = $rowupdate."Owner Email"
        $rowworking.givenname       = $rowupdate.givenname
        $rowworking.sn              = $rowupdate.sn
        $rowworking.manager         = $rowupdate.manager
        $rowworking.Level2          = $rowmaster.Level2
        $rowworking.Level3          = $rowmaster.Level3
        $rowworking.Level4          = $rowmaster.Level4

        $arrworking += $rowworking
    }
}

$arrworking | Export-Csv -Force -NoTypeInformation c:\temp\arrmaster.csv

Not tested, but I think this should work:未经测试,但我认为这应该有效:

$MasterFile = 'c:\somedir\master.csv'
$UpdateFile = 'c:\somedir\update.csv'

$master= @{}
$update = @{}

import-csv $MasterFile |
ForEach-Object { $master[$_.accountname] = $_ }

import-csv $update |
ForEach-Object { $update[$_.accountname] = $_ }

#Get Master entries contained in Update 
[array]$NewArray = $master.keys |
 Where-Object { $update.keys -contains $_ } |
 ForEach-Object { $master[$_] }

 #Get Updates not in Master
 $NewArray += $update.keys | 
 Where-Object { $master.keys -notcontains $_ } |
 ForEach-Object { $update[$_] }

 $NewArray | Export-Csv 'c:\somedir\new_master.csv' -NoTypeInformation

That starts by loading each of your arrays into a hash table, indexed by the accountname.首先将您的每个数组加载到一个哈希表中,由帐户名索引。 Then the keys are used to extract the master entries that have an accountname that appears in the update keys and load that into a new array.然后,密钥用于提取具有出现在更新密钥中的帐户名的主条目,并将其加载到新数组中。 Then the process is reversed and the update keys compared to the master keys, and any entries that do not have a matching key in the master are added to the array.然后反向执行该过程,将更新密钥与主密钥进行比较,并将主密钥中没有匹配密钥的任何条目添加到数组中。 Then the array is exported to csv.然后将数组导出到 csv。

The CSV export will create it's header row from the first entry, and add the necessary commas for any objects in the array afterward that are missing properties. CSV 导出将从第一个条目创建它的标题行,然后为数组中缺少属性的任何对象添加必要的逗号。 You don't have to worry about adding the missing properties to the update entries as long as they're added after the master entries.您不必担心将缺少的属性添加到更新条目,只要它们是在主条目之后添加的。

Ok, again based off the assumption that AccountName is a unique identifier that both lists would have in common you can run this:好的,再次基于 AccountName 是两个列表共有的唯一标识符的假设,您可以运行以下命令:

$Master = Import-CSV Master.csv
$Update = Import-CSV Update.csv
$T2Keys = $Master|gm|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$T1Keys = $Update|gm|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$KeysToAdd = $T2Keys|?{$T1Keys -notcontains $_}
$NewMaster = @()
$NewMaster += $Update | ?{!($Master.accountname -contains $_.accountname)}
$KeysToAdd|%{$NewMaster|Add-Member $_ ""}
$NewMaster += $Master | ?{$Update.accountname -contains $_.accountname}
$Newmaster| Select ef,ea,rem,accountname,enabled,passwordlastset,whencreated,description,'owner email',givenname,sn,manager,level2,level3,level4|Export-CSV NewMaster.csv -notype

Ok, that will import a CSV for the master list and the updates list.好的,这将为主列表和更新列表导入 CSV。 If you already have those as objects then skip the import-csv lines.如果您已经将它们作为对象,则跳过 import-csv 行。 Then it gets all properties from both, and figures out which ones to add to the updates (the 6 that the master has that the updates doesn't).然后它从两者中获取所有属性,并找出要添加到更新中的属性(主服务器拥有的 6 个属性,而更新没有)。 It then creates an empty array and adds all records from the Updates list to it that aren't in the master list.然后它创建一个空数组并将更新列表中所有不在主列表中的记录添加到它。 Then it adds the missing fields, and adds all the records from the master list that are in the updates list.然后添加缺失的字段,并添加更新列表中主列表中的所有记录。 Then it exports it to a CSV.然后将其导出为 CSV。 So it does what you asked:所以它做你问的:

  • Gets all records from the master list that are in both lists.从主列表中获取两个列表中的所有记录。
  • Adds records from the update list that are missing from the master list.从更新列表中添加主列表中缺失的记录。

Edit: The reason I had asked if you had searched is that 95% of my answer there was almost copied and pasted from this question that I answered just under a month ago.编辑:我问你是否搜索过的原因是,我的答案的 95% 几乎是从我不到一个月前回答的这个问题中复制和粘贴的。 But hey, it's all good, not that hard for me to copy and paste to get you an answer, and I kinda knew what I was looking for anyway.但是,嘿,这一切都很好,对我来说复制和粘贴以获得答案并不难,而且无论如何我都知道我在寻找什么。 I don't know that the other question's title would have been indicative that it had what you needed.我不知道另一个问题的标题是否表明它有你需要的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM