【问题标题】:Create Multiple arrays from a CSV file从 CSV 文件创建多个数组
【发布时间】:2015-12-29 14:26:32
【问题描述】:

目前我有一个可行的解决方案:

#Declare Variables
$PMArray = @()
$SMArray = @()

#Get Input File and put information in 2 Arrays, 1 for Personal Mailboxes
#and 1 for Shared Mailboxes

Import-Csv "C:\inputfile.csv" -Delimiter ';' | foreach {
    $InputMBXType =  $_."MailboxType"
    $InputL =  $_."Level"
    $InputSMTP =  $_."PrimarySMTPAddress"

    if ($InputMBXType -eq "Personal Mailbox") {
        $PMObject = New-Object psobject
        $PMObject | Add-Member NoteProperty 'MailboxType' $InputMBXType
        $PMObject | Add-Member NoteProperty 'Level' $InputL
        $PMObject | Add-Member NoteProperty 'EmailAddress' $InputSMTP

        $PMArray += $PMObject
    }

    if ($InputMBXType -eq "Shared Mailbox") {
        $SMObject = New-Object psobject
        $SMObject | Add-Member NoteProperty 'MailboxType' $InputMBXType
        $SMObject | Add-Member NoteProperty 'Level' $InputL
        $SMObject | Add-Member NoteProperty 'EmailAddress' $InputSMTP

        $SMArray += $SMObject
    }
}

#Split Arrays by department

#Personal Mailboxes
$ABCpmarray = $PMArray | Where-Object {$_.Level -eq "ABC"}
$DEFpmarray = $PMArray | Where-Object {$_.Level -eq "DEF"}
$GHIpmarray = $PMArray | Where-Object {$_.Level -eq "GHI"}

#Shared Mailboxes
$ABCsmarray = $SMArray | Where-Object {$_.Level -eq "ABC"}
$DEFsmarray = $SMArray | Where-Object {$_.Level -eq "DEF"}
$GHIsmarray = $SMArray | Where-Object {$_.Level -eq "GHI"}

#Split Array in batches of defined number per batch
[int]$splitat = 50

#ABCpmarray
$runcount = [math]::Ceiling($ABCpmarray.count/$splitat)
for ($LN=0; $LN -lt $runcount; $LN++) {
    [int]$begin = $($LN * $splitat)
    [int]$end = $(($LN +1) * $splitat) -1
    $count = "{0:D2}" -f $LN
    $sel = $ABCpmarray[$begin..$end]
    $sel | select EmailAddress | Export-Csv -Path "C:\ABC-Personal-$count.csv" -NoTypeInformation
}

#ABCsmarray
$runcount = [math]::Ceiling($ABCsmarray.count/$splitat)
for ($LN=0; $LN -lt $runcount; $LN++) {
    [int]$begin = $($LN * $splitat)
    [int]$end = $(($LN +1) * $splitat) -1
    $count = "{0:D2}" -f $LN
    $sel = $ABCsmarray[$begin..$end]
    $sel | select EmailAddress | Export-Csv -Path "C:\ABC-Shared-$count.csv" -NoTypeInformation
}

#DEFpmarray
$runcount = [math]::Ceiling($DEFpmarray.count/$splitat)
for ($LN=0; $LN -lt $runcount; $LN++) {
    [int]$begin = $($LN * $splitat)
    [int]$end = $(($LN +1) * $splitat) -1
    $count = "{0:D2}" -f $LN
    $sel = $DEFpmarray[$begin..$end]
    $sel | select EmailAddress | Export-Csv -Path "C:\DEF-Personal-$count.csv" -NoTypeInformation
}

#DEFsmarray
$runcount = [math]::Ceiling($DEFsmarray.count/$splitat)
for ($LN=0; $LN -lt $runcount; $LN++) {
    [int]$begin = $($LN * $splitat)
    [int]$end = $(($LN +1) * $splitat) -1
    $count = "{0:D2}" -f $LN
    $sel = $DEFsmarray[$begin..$end]
    $sel | select EmailAddress | Export-Csv -Path "C:\DEF-Shared-$count.csv" -NoTypeInformation
}

不幸的是,所有部门都在脚本中硬编码。

我想对所有部门使用 CSV 文件。 基于 CSV,必须创建新数组并填充内容。

【问题讨论】:

  • @mkierc 我已经阅读了您建议的帖子,但我的问题与您建议的帖子不同。
  • @ThomasMuller 虽然这可能是真的,但值得解释一下为什么。不仅仅是简单地说它是不同的。
  • 这里有很多重复的代码。出于 MCVE 的目的,您能否将其简化为一个简单的集合并展示您如何手动创建它们? $_.Level -eq "ABC" 是硬编码部门的意思吗?什么是$PMArray 和$SMArray
  • 一个好的第一步可能是重构数组过滤和for循环成一个函数。

标签: arrays csv powershell


【解决方案1】:

你真的不需要单独的数组。从外观上看,您只是使用这些数组来帮助将输出解析为不同的文件。信息都在那里,您可以直接从Import-CSV 解析。作为shown by JohnLBeven,我们可以使用 Group-Object 来替换您在创建数组时使用的大部分逻辑。

我使用 www.mockaroo.com 模拟了一些用于测试的数据

MailboxType      PrimarySMTPAddress         Level
-----------      ------------------         -----
Personal Mailbox dgonzalesb@imageshack.us   ABC  
Shared Mailbox   klong9@cbc.ca              ABC  
Shared Mailbox   kchapman1@arstechnica.com  ABC  
Personal Mailbox pbowmanf@deliciousdays.com DEF  
Personal Mailbox charris5@addthis.com       DEF  
Personal Mailbox jhughesi@addtoany.com      DEF  
Shared Mailbox   chuntg@sun.com             DEF  
Shared Mailbox   apalmerd@163.com           DEF  
Shared Mailbox   dperez8@chron.com          DEF  
Shared Mailbox   jwilsona@nature.com        DEF  
Shared Mailbox   khayesc@nhs.uk             DEF  
Personal Mailbox jnelsonh@newsvine.com      GHI  
Personal Mailbox epetersone@microsoft.com   GHI  
Personal Mailbox sfuller0@forbes.com        GHI  
Personal Mailbox swoods6@taobao.com         GHI  
Personal Mailbox kbradley4@ft.com           GHI  
Personal Mailbox chill3@umn.edu             GHI  
Personal Mailbox jgarza2@guardian.co.uk     GHI  
Personal Mailbox sturner7@moonfruit.com     GHI  
Shared Mailbox   swagnerj@amazon.de         GHI  

$rawdata = Import-CSV 'C:\MOCK_DATA.csv' -Delimiter ';'
$exportFolder = "C:\temp\test"
# Max number of entries per output file.
[int]$carve = 3

# Group 
$rawdata | Group-Object MailboxType | ForEach-Object{
    # Data is now grouped by MailboxType.
    $currentType = $_.Name -replace "\s+Mailbox$"s

    # Group this data by Level now
    $_.Group |  Group-Object Level | ForEach-Object{

        # Carve up the elements into chucks. Each group then written to its own file.
        for([int]$index = 0;$index -lt $_.Group.Count;$index+=$carve){ 

            # Collect the current chuck and send it to its own file. 
            $_.Group[$index..($index + $carve - 1)] | 
                Select @{Name="EmailAddress";Expression={$_.PrimarySMTPAddress}} |
                Export-CSV -NoTypeInformation -Path ("$exportfolder\{0}-{1}-{2:D2}.csv" -f $_.Name, $currentType, ($index / $Carve + 1))
        }
    }
}

邮箱类型的第一组。然后按级别分组。根据$carve 整数划分这些数组。根据所有这些属性导出自定义文件名。

使用我上面的测试数据创建了以下 csv 文件

ABC-Personal-01.csv                                                                                                                        
ABC-Shared-01.csv                                                                                                                          
DEF-Personal-01.csv                                                                                                                        
DEF-Shared-01.csv                                                                                                                          
DEF-Shared-02.csv                                                                                                                          
GHI-Personal-01.csv                                                                                                                        
GHI-Personal-02.csv                                                                                                                        
GHI-Personal-03.csv                                                                                                                        
GHI-Shared-01.csv 

【讨论】:

  • 谢谢马特。您的脚本完成了这项工作。这样看起来干净多了!
【解决方案2】:
  1. Group-Object 功能几乎可以满足您的需求;所有数据将被放入一个对象中,但您可以使用组名拉回相关组的数组:

    $AllArrays = $PMArray | Group-Object -Property Level
    
    $AllArrays | %{
        "Group Name: $($_.Name)" 
        $_ | select -ExpandProperty Group | ft -HideTableHeaders 
    }
    
  2. 您可以通过简单地从 CSV 中提取值并进行如下过滤,从而为 foreach 循环节省一些精力:

    [psobject[]]$PMArray = Import-Csv "C:\inputfile.csv" -Delimiter ';' `
    | ?{$_.MailboxType -eq "Personal Mailbox"} `
    | select MailboxType, Level, @{Name = 'EmailAddress'; Expression = {$_.PrimarySMTPAddress}}
    
    [psobject[]]$SMArray = Import-Csv "C:\inputfile.csv" -Delimiter ';' `
    | ?{$_.MailboxType -eq "Shared Mailbox"} `
    | select MailboxType, Level, @{Name = 'EmailAddress'; Expression = {$_.PrimarySMTPAddress}}
    

【讨论】:

    猜你喜欢
    • 2017-01-20
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2022-10-15
    • 2012-10-14
    相关资源
    最近更新 更多