【问题标题】:How to split single column (Have multiple value) into multi value through powershell如何通过powershell将单列(具有多个值)拆分为多值
【发布时间】:2025-11-22 05:25:02
【问题描述】:

我有 CSV 文件,它在单列中包含多个值,我想将每个值拆分到下一列。请在下面找到图片

我正在使用以下代码,但没有任何运气:

$CSVpath1 = "G:\Test.csv"
$csv = Import-Csv -Path $CSVpath1 -Delimiter ';'
$p= (Get-Member -InputObject $csv[0] -MemberType Properties).Name
foreach ($property in $p) {
    $csv | Select-Object @{n=$p;e={$_.$p}} |
        Export-Csv -LiteralPath "$p.csv" -NoTypeInformation -Delimiter ';'
}

请查找附件 CSV 文件:Test CSV

【问题讨论】:

  • 你不是昨天还是几天前就问过这个问题了?
  • @Olaf 我觉得有点不同。
  • @Steven ... 嗯...有些人可能会对此争论不休。 ;-) ...但是既然你已经回答了...
  • @Olaf 可能我被不同的标题,分隔符等抛出......希望这不是家庭作业,哈哈。
  • @Daniel 我在答案中引用的那个仍然存在,如果你想看看的话。如果您想发布它等,您的方法也可能在那里相关。

标签: powershell csv


【解决方案1】:

看起来类似于this answer。将字符串操作与本机 Csv cmdlet 混合使用的类似技术。

$CSVpath = "c:\temp\test1.csv"
$Data    = Get-Content $CSVpath
$Headers = $Data[0] -split ','

$Data = ($Data | Select-Object -Skip 1) -replace '\"|,'    
    
$Data | ConvertFrom-Csv -Header $Headers -Delimiter ";" 

引入文件,使用第一行确定标题。然后使用带有-Headers-Delimiter 参数的ConvertFrom-Csv cmdlet 将剩余的行从CSV 转换为PSObjects。还替换了看起来多余的引用。

这将导致对象看起来像:

H1 h2 H3 H4  H5 H6 H7                 H8 H9 H10
-- -- -- --  -- -- --                 -- -- ---
A  B  C  D   E  F  G,,,,,,,,,,,,,,,,,
H  I  J  K   L  M  N                  O  P  Q
A  B  C  D   E  F  G,,,,,,,,H         I  J  K
10 a  C  D,H I  J  K                  L  M  N

但是,尚不清楚要使用逗号做什么。我建议事先清理数据。

替换上一个答案中的逗号并覆盖原始文件:

$CSVpath = "c:\temp\test1.csv"
$Data    = Get-Content $CSVpath
$Headers = $Data[0] -split ','

$Data = ($Data | Select-Object -Skip 1) -replace '\"|,'

$Data | ConvertFrom-Csv -Header $Headers -Delimiter ";" | 
Export-Csv -Path $CSVpath -Delimiter ";" -NoTypeInformation

尽管导出,这应该是这样的:

H1 h2 H3 H4 H5 H6 H7 H8 H9 H10
-- -- -- -- -- -- -- -- -- ---
A  B  C  D  E  F  G
H  I  J  K  L  M  N  O  P  Q
A  B  C  D  E  F  GH I  J  K
10 a  C  DH I  J  K  L  M  N

注意:两个表都是使用Format-Table 输出的,默认情况下会截断一些列。使用Format-Table * -AutoSize 查看完整表格。

所有都可以缩短为:

$CSVpath = "c:\temp\test1.csv"
$Data    = Get-Content $CSVpath
$Headers = $Data[0] -Split ','

($Data | Select-Object -Skip 1) -replace '\"|,' |
ConvertFrom-Csv -Header $Headers -Delimiter ";" | 
Export-Csv -Path $CSVpath -Delimiter ";" -NoTypeInformation

# To trim superfluous ";" belonging to emty fields.
(Get-Content $CSVpath).TrimEnd(';') | Set-Content $CSVpath

注意:对于真正的 Csv 文件,没有必要删除结尾的 ;。它们是没有值的属性的自然表示。无论如何,根据请求,我添加了一些代码来删除它们。

【讨论】:

  • 史蒂文,感谢您回答我的问题,感谢。我已经运行了最后一个脚本,但仍然没有得到你提到的结果,我得到了以下结果:H1;“h2”;“H3”;“H4”;“H5”;“H6”;“H7”;“H8” ;"H9";"H10";"H11";"H12";"H13";"H14";"H15";"H16";"H17";"H18" A;"B";"C"; “D”;“E”;“F”;“G”;;;;;;;;;;;最后的代码有什么遗漏吗?
  • 代码没有问题。文件中多余的;是因为原始数据中有空字段。文件的第一个数据行有 7 条数据,但有 18 个字段由表头定义。因此,当它被导出时, emty 属性值看起来就是这样。注意:输出到表会截断列。作为测试,您可以强制它显示以下所有内容:Import-Csv "C:\temp\test1.csv" -Delimiter ";" | Format-Table *
  • 有什么解决办法吗?
  • 虽然我认为对于真正的 Csv 文件没有必要,但我添加了一些代码来清除它们。假设它正在工作,请考虑接受答案。谢谢。
  • @Nilam 我想我已经解决了问题范围内的所有问题。如果你觉得舒服,你能接受这个答案吗,它可以帮助其他人找到它并从中学习。