Powershell 哈希表导出为 CSV
Powershell Hashtable Export to CSV
我正在尝试创建一个 CSV 导出文件,其中包含搜索电子表格中显示 ID 的数据电子表格中的所有行。
我现在已经设法通过 PowerShell 创建了搜索元素,但在将数据导出为 CSV 格式时遇到了问题。
下面是一些示例表,实际数据最多有8个值(包括ID列),但只有前三个是gua运行需要填充的。
数据电子表格
+------+---------+---------+---------+---------------------+
| 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
+------------+-------------+----------------+--------------------------------------------+----------------------------------------------+---------------+-------+
| 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 |
+-------+------------+-------------+---------------+----------------+
这可以通过使用 Where-Object
filter and then exporting with Export-CSV
来简化。
$Search = Import-CSV "SEARCH.csv"
Import-CSV "DATA.csv" | Where-Object {$Search.ID -Contains $_.ID} | Export-CSV C:\exampleexportpath.csv -NoTypeInformation
is clearly a better way to implement this, but I just wanted to explain what the issue was with your original code. The problem is that $data
is a HashTable
mapping a string
(the user ID
) to an array (actually it's a 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.Values
到 Export-Csv
的输出表现得好像值是数组;这是因为他们是。
要解决此问题,当访问 $data
中的项目时,我们需要一个内部循环来 "unwrap" 每个值。此外,我们不能将 HashTable
用于 $finalValues
,因为您使用 ID
作为键,但其中有重复的 ID
s ('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"
我正在尝试创建一个 CSV 导出文件,其中包含搜索电子表格中显示 ID 的数据电子表格中的所有行。
我现在已经设法通过 PowerShell 创建了搜索元素,但在将数据导出为 CSV 格式时遇到了问题。
下面是一些示例表,实际数据最多有8个值(包括ID列),但只有前三个是gua运行需要填充的。
数据电子表格
+------+---------+---------+---------+---------------------+
| 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
+------------+-------------+----------------+--------------------------------------------+----------------------------------------------+---------------+-------+
| 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 |
+-------+------------+-------------+---------------+----------------+
这可以通过使用 Where-Object
filter and then exporting with Export-CSV
来简化。
$Search = Import-CSV "SEARCH.csv"
Import-CSV "DATA.csv" | Where-Object {$Search.ID -Contains $_.ID} | Export-CSV C:\exampleexportpath.csv -NoTypeInformation
$data
is a HashTable
mapping a string
(the user ID
) to an array (actually it's a 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.Values
到 Export-Csv
的输出表现得好像值是数组;这是因为他们是。
要解决此问题,当访问 $data
中的项目时,我们需要一个内部循环来 "unwrap" 每个值。此外,我们不能将 HashTable
用于 $finalValues
,因为您使用 ID
作为键,但其中有重复的 ID
s ('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"