簡體   English   中英

Powershell Hashtable導出為CSV

[英]Powershell Hashtable Export to CSV

我正在嘗試創建一個CSV導出,其中包含數據電子表格中搜索電子表格中顯示ID的所有行。

我已經設法通過PowerShell創建搜索元素,但是在將數據導出為CSV格式時遇到了問題。

下面是一些示例表,實際數據最多有8個值(包括ID列),但只保證填充前三個。

數據電子表格

+------+---------+---------+---------+---------------------+ | ID | Value 1 | Value 2 | Value 3 | Value 4 | +------+---------+---------+---------+---------------------+ | 1234 | London | Serial1 | HP | Laptop User | | 2345 | Moscow | Serial7 | | HR Application | | 1234 | London | Serial9 | | Finance Application | | 3456 | Madrid | Serial4 | HP | Laptop User | +------+---------+---------+---------+---------------------+

搜索電子表格

+------+ | ID | +------+ | 1234 | | 2345 | +------+

期望的結果

+------+---------+---------+---------+---------------------+ | ID | Value 1 | Value 2 | Value 3 | Value 4 | +------+---------+---------+---------+---------------------+ | 1234 | London | Serial1 | HP | Laptop User | | 2345 | Moscow | Serial7 | | HR Application | | 1234 | London | Serial9 | | Finance Application | +------+---------+---------+---------+---------------------+

下面是我刪除導出到CSV的嘗試的當前代碼。

$finalValues = @{}

$users = Import-Csv "SEARCH.csv"

$data = Import-Csv "DATA.csv" | Group-Object -property ID -AsHashTable

foreach ($user in $users) 
{
    If ($data.Contains($user.ID))
    {
        #write-output $data[$user.ID].ID
        $finalValues.Add($data[$user.ID].ID, $data[$user.ID])
    }
}

以下兩個命令(在執行其余腳本后運行)具有以下輸出。

$finalValues.Values

ID      : 1234
Value 1 : London
Value 2 : Serial 1
Value 3 : HP
Value 4 : 
Value 5 : 
Value 6 : 
Value 7 : Laptop User

ID      : 2345
Value 1 : Moscow
Value 2 : Serial7
Value 3 : 
Value 4 : 
Value 5 : 
Value 6 : 
Value 7 : HR Application

ID      : 1234
Value 1 : London
Value 2 : Serial9
Value 3 : 
Value 4 : 
Value 5 : 
Value 6 : 
Value 7 : Finance Application

$finalValues

{1234, 1234}             {@{ID=1234; Value 1=London; Value 2=Serial1; Value 3=HP; Value 4=; Value 5=; Value 6=; Value 7=Laptop User}, @{ID=1234; Value 1=London; Value 2=Serial 9... ; Value 7 =Finance Application}}

2345                        {@{ID=2345; Value 1=Moscow; Value 2=Serial7; Value 3=; Value 4=; Value 5=; Value 6=; Value 7=HR Application}}           

使用以下命令導出到CSV時,我得到以下結果: $finalValues | export-csv -Path test.csv -NoTypeInformation $finalValues | export-csv -Path test.csv -NoTypeInformation

+------------+-------------+----------------+--------------------------------------------+----------------------------------------------+---------------+-------+
| IsReadOnly | IsFixedSize | IsSynchronized |                    Keys                    |                    Values                    |   SyncRoot    | Count |
+------------+-------------+----------------+--------------------------------------------+----------------------------------------------+---------------+-------+
| FALSE      | FALSE       | FALSE          | System.Collections.Hashtable+KeyCollection | System.Collections.Hashtable+ValueCollection | System.Object |    14 |
+------------+-------------+----------------+--------------------------------------------+----------------------------------------------+---------------+-------+

使用以下命令導出到CSV時,我得到以下結果:

$finalValues.Values | export-csv -Path test.csv -NoTypeInformation

+-------+------------+-------------+---------------+----------------+
| Count | IsReadOnly | IsFixedSize |   SyncRoot    | IsSynchronized |
+-------+------------+-------------+---------------+----------------+
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     3 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     2 | FALSE      | FALSE       | System.Object | FALSE          |
|     2 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     2 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
|     1 | FALSE      | FALSE       | System.Object | FALSE          |
+-------+------------+-------------+---------------+----------------+

@ BenH的答案顯然是實現這一目標的更好方法,但我只想解釋原始代碼的問題。 問題是$data是一個HashTable ,它將一個string (用戶ID )映射到一個數組 (實際上它是一個Collection<PSObject>但出於我們的目的,它的行為相同)。 即使在ID '2345'且只有一個匹配記錄的情況下, $data仍將其存儲為具有一個元素的數組:

PS> $data['2345'].GetType().Name
Collection`1
PS> $data['2345'].Count
1
PS> $data['2345']    # Returns the array of values


ID      : 2345
Value 1 : Moscow
Value 2 : Serial7
Value 3 :
Value 4 : HR Application


PS> $data['2345'][0] # Returns the first element of the array of values


ID      : 2345
Value 1 : Moscow
Value 2 : Serial7
Value 3 :
Value 4 : HR Application

因此,當這一行執行時......

$finalValues.Add($data[$user.ID].ID, $data[$user.ID])

...您正在向$data添加一個新項目,其中鍵和值都是數組。 這就是為什么輸出管道$finalValues$finalValues.ValuesExport-Csv行為就像值是數組一樣; 這是因為他們是。

要解決這個問題,當訪問$data項目時,我們需要一個內部循環來“解包”每個值。 此外,我們不能將$finalValues HashTable用於$finalValues因為您使用ID作為鍵,但結果中有重復的ID'1234' )。 由於我們所需要的是一個最終傳遞給Export-Csv的記錄列表,我們可以使用數組代替。 這是一些修改過的代碼......

$finalValues = @() # Cannot be a HashTable because there may be multiple results with the same ID

$users = Import-Csv "SEARCH.csv"

$data = Import-Csv "DATA.csv" | Group-Object -property ID -AsHashTable

foreach ($user in $users)
{
    If ($data.Contains($user.ID))
    {
        # "Unwrap" the array stored at $data[$user.ID]
        foreach ($dataRecord in $data[$user.ID])
        {
            $finalValues += $dataRecord
        }
    }
}

$finalValues | Export-Csv -Path test.csv -NoTypeInformation

...產生這個CSV ...

"ID","Value 1","Value 2","Value 3","Value 4"
"1234","London","Serial1","HP","Laptop User"
"1234","London","Serial9","","Finance Application"
"2345","Moscow","Serial7","","HR Application"

這可以通過使用Where-Object過濾器然后使用Export-CSV簡化。

$Search = Import-CSV "SEARCH.csv"
Import-CSV "DATA.csv" | Where-Object {$Search.ID -Contains $_.ID} | Export-CSV C:\exampleexportpath.csv -NoTypeInformation

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM