我有两个从csv文件导入的数组,从这里我将称为主数组和更新数组。
主阵列正面有三个额外的列,背面有三个额外的列。
每天我都会得到一个新的更新数组,我需要做两件事。
A)删除主服务器上未出现在更新中的所有行
B)将更新中出现的但不是主要的行添加到主
我仍然是PowerShell的新手,一般来说是脚本(大多是自学),也无法弄清楚如何处理这个问题。我知道有一个比较对象命令,所以我可以很容易地得到哪些行匹配的列表,但我不确定如何按照我想要的方式组合它们。
编辑: 主阵列条目具有以下信息:
ef:是的
ea:真实的
rem:真实的
accountname:example1
启用:真实
PasswordLastSet:01/08/2002 13:14:19
whencreated:01/08/2002 13:14:19
说明:
所有者电子邮件:johnsmith@email.com
名字:约翰
sn:史密斯
经理:John Doe
Level2:人1
Level3:人2
Level4:人3
虽然更新只有:
accountname:example1
启用:真实
PasswordLastSet:01/08/2002 13:14:19
whencreated:01/08/2002 13:14:19
说明:
所有者电子邮件:johnsmith@email.com
名字:约翰
sn:史密斯
经理:John Doe
答案 0 :(得分:0)
假设accountname列可以用作将两个数组绑定在一起的唯一键,您可以使用类似下面的脚本。它会创建第三个数组,然后在完成后覆盖主数组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
答案 1 :(得分:0)
未经测试,但我认为这应该有效:
$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
首先将每个数组加载到一个哈希表中,并以accountname为索引。然后,密钥用于提取具有出现在更新密钥中的帐户名的主条目,并将其加载到新数组中。然后,该过程相反,更新密钥与主密钥进行比较,并且主服务器中没有匹配密钥的任何条目都将添加到数组中。然后将数组导出到csv。
CSV导出将从第一个条目创建它的标题行,并为之后缺少属性的数组中的任何对象添加必要的逗号。只要在主条目之后添加了更新条目,您就不必担心将缺少的属性添加到更新条目中。
答案 2 :(得分:0)
好的,再次假设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
好的,这将导入主列表和更新列表的CSV。如果您已将这些作为对象,则跳过import-csv行。然后它从两者中获取所有属性,并确定要添加到更新中的哪些属性(主要具有更新的6)。然后它创建一个空数组,并将更新列表中的所有记录添加到不在主列表中的记录。然后,它会添加缺少的字段,并添加主列表中更新列表中的所有记录。然后将其导出为CSV。所以它就是你所要求的:
编辑:我之所以问你是否有搜索的原因是我的答案的95%几乎是在this question复制并粘贴的,我在一个月前就回答了。但是,嘿,这一切都很好,对我来说并不难以复制和粘贴以获得答案,而且无论如何我都知道我在寻找什么。我不知道另一个问题的标题是否表明它有你需要的东西。