使用PowerShell将分号分隔文本文件转换为CSV时数据写入失败的问题排查
解决PowerShell无法正确写入CSV文件的问题
我来帮你排查代码里的问题,顺便给你修正后的实用方案。先看看你的代码哪里出问题了:
代码里的核心问题
- 错误使用
Export-Csv处理纯文本:你把替换了分隔符的字符串直接传给Export-Csv,但这个 cmdlet 是用来处理PowerShell对象的,不是纯文本行。当你传入字符串时,它只会导出字符串的内置属性(比如Length),但你的CSV表头是自定义的,所以就出现了空值的情况。 - 多余的空对象写入:一开始你创建了一个空的
PsObject并写入CSV,这直接导致输出里多了一行空数据。 - 表头处理不当:原文件的第一行其实包含了表头信息,但你直接跳过了前2行,虽然示例里第二行是数据,但如果其他文件结构一致,应该只跳过第一行的状态部分,提取正确的表头。
修正后的代码方案
最可靠的方法是直接用Import-Csv指定原文件的分隔符为;,它会自动把每行转换成带属性的对象,然后直接导出为默认逗号分隔的CSV,完全不需要手动替换分隔符:
$outputPath = "C:\2021.csv" $fileList = Get-ChildItem -Path "C:\Files" # 先清空输出文件(如果需要覆盖原有内容) $null | Out-File -Path $outputPath -Force foreach ($n_file in $fileList) { # 读取文件,跳过第一行的状态行,从第二行开始导入,指定分隔符为; $data = Import-Csv -Path $n_file.FullName -Delimiter ";" -Header "ServerName", "SystemFolderPath", "IdenityReference", "FileSystemRights", "Vulnerable" | Select-Object -Skip 1 # 追加到输出CSV $data | Export-Csv -Path $outputPath -Append -NoTypeInformation -Force }
代码解释
Import-Csv -Delimiter ";":直接识别原文件的分号分隔格式,把每行转换成带有你指定表头属性的对象。-Header参数:因为原文件的第一行是状态行(B97SW | CHANGED | rc=0 >> ...),我们跳过第一行后,用-Header指定自定义的表头,这样数据行就能正确映射到对应的属性。Select-Object -Skip 1:跳过原文件的第一行状态信息,从第二行开始读取数据。- 避免空对象写入:不需要提前写入空对象,直接通过
Import-Csv获取数据对象后导出即可。
如果你坚持要手动处理文本行(不推荐,容易因特殊字符出错),也可以这样写:
$outputPath = "C:\2021.csv" $fileList = Get-ChildItem -Path "C:\Files" $headers = "ServerName","SystemFolderPath","IdenityReference","FileSystemRights","Vulnerable" # 先写入表头 $headers -join "," | Out-File -Path $outputPath -Force foreach ($n_file in $fileList) { $fileContent = Get-Content -Path $n_file.FullName | Select-Object -Skip 1 foreach ($line in $fileContent) { # 替换分号为逗号,然后写入文件 $line -replace ";", "," | Out-File -Path $outputPath -Append -Force } }
这个方法直接处理纯文本,先写入表头,再把每行的分号替换成逗号追加进去,适合简单的格式转换,但如果数据里包含逗号或者引号,可能会出现CSV格式错误,所以还是优先用Import-Csv的方案更稳妥。
内容的提问来源于stack exchange,提问作者Empty Coder
相关产品推荐
相关产品推荐

