2015-12-25 128 views
0

我想創建一個字典列表,以便將其導出爲CSV。正如你可能在PowerShell中所知道的那樣,如果你想將一個填充了字符串的數組導出爲CSV文件,它將不起作用,所以我必須爲此創建對象。Powershell字典或哈希表的列表

但是我這樣做的方式,如果迴避,我不覺得這是創建一個字典/散列表的正確方式,但我沒有創建一個函數重複的代碼(對不起) 。

#add the log file. 
$savegrp = Get-Content "J:\savegrp.dec.2015.log" 
#filtering into a var just Succeeded/Failed data then replace space with ';' and remove ',' 
$succeded = ($savegrp -cmatch "Succeeded:") -replace "\s+",";" -replace ",","" 
$failed = ($savegrp -cmatch " Failed: ") -replace "\s+",";" -replace ",","" 

#creating container where all data will be added 
$container = @() 
#just a date to save the csv file if this script will be scheduled 
$date = Get-Date -format dd.MMMM.yyyy 

#take each line of data with 'Succeeded' match and iterate it 
for($i=0;$i -le ($succeded.count-1);$i++) { 

    #split each line by ';' to see how many items are per one line 
    $s1 = ($succeded[$i]).split(";") 

    #if in one 'Succeeded' line are just 6 element then is just one server which is ok 
    if ($s1.count -eq 6){ 

     $PropertyHash = @{} 
     $PropertyHash = @{ 
      "Date" = $s1[1] + " " + $s1[0] 
      "Time" = $s1[2] 
      "Client" = $s1[5] 
      "Status" = $s1[4].Substring(0,9) 
     } 
     $container += New-Object -TypeName PSObject -Property $PropertyHash 
    } 
    #if in one 'Succeeded' line are more servers, then stick all sererers to the same info in the line 
    else{ 
     $count = ($s1.count) 

     for($a = $count-1;$a -ge 5){ 

      $PropertyHash = @{} 
      $PropertyHash += @{ 
       "Date" = $s1[1] + " " + $s1[0] 
       "Time" = $s1[2] 
       "Client" = $s1[$a] 
       "Status" = $s1[4].Substring(0,9) 
      } 
      $container += New-Object -TypeName PSObject -Property $PropertyHash 
      $a-- 
     } 
    } 
} 
+0

是啊,我有5個元素,併線,5號線+ n個元素,所以我想要隔離 – Xao

+0

GetEnumerator()? $ PropertyHash = [PSCustomObject] @ {}? –

回答

1

像這樣的東西應該工作得很好,只要你有PowerShell的V3或更新:

for ($i = 0; $i -lt $succeded.Count; $i++) { 
    $date1, $date2, $time, $null, $status, $clients = $succeded[$i].Split(';') 
    $clients | ForEach-Object { 
    New-Object -Type PSObject -Property @{ 
     'Date' = "$date2 $date1" 
     'Time' = $time 
     'Client' = $_ 
     'Status' = $status.Substring(0,9) 
    } 
    } | Export-Csv 'C:\path\to\output.csv' -NoType -Append 
} 

PowerShell允許數組分配給變量的列表,每一個從接受一個元素該數組除了最後一個,它接受所有剩餘的數組元素。聲明

$date1, $date2, $time, $null, $status, $clients = $succeded[$i].Split(';') 

收集日期,時間和狀態的各個變量$date1$date2$time$status。通過將其分配給$null來丟棄第4個值。由分割操作(客戶端列表)產生的數組的其餘部分分配給「全部捕獲」變量$clients。然後,您可以將該變量傳送到ForEach-Object聲明中,在該語句中爲每個客戶端創建一個對象並將它們附加到您的CSV文件(請注意,您至少需要PowerShell v3才能附加到CSV)。

編輯:如果您遇到PowerShell v2或更早的版本,您還可以在循環之外進行導出。然而,對於工作,你需要或者在一個子表達式運行它:

(for ($i = 0; $i -lt $succeded.Count; $i++) { 
    $date1, $date2, $time, $null, $status, $clients = $succeded[$i].Split(';') 
    $clients | ForEach-Object { 
    New-Object -Type PSObject -Property @{ 
     'Date' = "$date2 $date1" 
     'Time' = $time 
     'Client' = $_ 
     'Status' = $status.Substring(0,9) 
    } 
    } 
}) | Export-Csv 'C:\path\to\output.csv' -NoType 

或先收集在一個變量的結果:

$container = for ($i = 0; $i -lt $succeded.Count; $i++) { 
    $date1, $date2, $time, $null, $status, $clients = $succeded[$i].Split(';') 
    $clients | ForEach-Object { 
    New-Object -Type PSObject -Property @{ 
     'Date' = "$date2 $date1" 
     'Time' = $time 
     'Client' = $_ 
     'Status' = $status.Substring(0,9) 
    } 
    } 
} 

$container | Export-Csv 'C:\path\to\output.csv' -NoType 
+1

爲什麼不把''''輸出到'Export-Csv'('&{for ...} | Export-Csv'),所以你不必追加? – PetSerAl

+1

@PetSerAl這將需要在子表達式或scriptblock中運行'for'循環,我試圖避免這種情況,因爲我覺得語法醜陋。一個scriptblock也會使'$ succeded'的處理稍微複雜一些。如果OP有PowerShell v2,我寧願在一個變量('$ container = for(...){...}')中收集循環結果並將其導出爲CSV。 –