使用ConvertFrom-Csv用换行符解析Powershell管道CSV数据

时间:2018-11-09 01:10:21

标签: powershell csv

当尝试使用字段内的换行符解析CSV数据时,ConvertFrom-Csv将无法正常工作。这是一个示例:


test.csv

name,address
John Doe,"123 Easy Way
Apt. 10
Somewhere, USA"
Jane Doe,"456 Main St
Unit 5
SomewhereElse, USA"

正确解析

> Import-Csv test.csv

name     address
----     -------
John Doe 123 Easy Way...
Jane Doe 456 Main St...

不正确的解析

> Get-Content test.csv | ConvertFrom-Csv

name          address
----          -------
John Doe      123 Easy Way
Apt. 10
Somewhere     USA"
Jane Doe      456 Main St
Unit 5
SomewhereElse USA"

如此处所示,换行被解析为新记录,而不是字段中的换行。您如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

当尝试使用字段内的换行符解析CSV数据时,会出现使用ConvertFrom-Csv方法的问题。这是由于换行符用作定界符,而不是传递给ConvertFromCsv方法。  根据获取CSV的方式的不同,解决方法也不同:

使用-Raw开关进行正确的解析

PS> Get-Content -raw test.csv | ConvertFrom-Csv

name     address
----     -------
John Doe 123 Easy Way...
Jane Doe 456 Main St...

虽然此方法适用于Get-Content命令,但不适用于可能将CSV返回到管道的任意命令。要解决这些情况,请通过“ Out-String”命令通过管道传递输出。

正确的管道解析

我发现有2种版本可以使用:

PS> <command> | Out-String | ConvertFrom-Csv

以下方法归功于#Powershell中的sifb。有点“ hacky”,但可以正常工作并且可以使用。

PS> (<command>) -join "`r`n" | ConvertFrom-Csv

答案 1 :(得分:0)

这很脆弱,因为每个记录都有硬编码的行数。但是,它适用于您的样本数据集。 [咧嘴]我怀疑精心编写的正则表达式可以更快地完成这项工作,但我无法提出这样的建议。

# fake reading in a text file
#    in real life, use "Get-Content"
$InStuff = @'
name,address
John Doe,"123 Easy Way
Apt. 10
Somewhere, USA"
Jane Doe,"456 Main St
Unit 5
SomewhereElse, USA"
'@ -split [environment]::NewLine

$CleanedInStuff = foreach ($Index in 0..$InStuff.GetUpperBound(0))
    {
    if ($Index -eq 0)
        {
        $InStuff[$Index]
        continue
        }
    if (-not [string]::IsNullOrEmpty($InStuff[$Index]))
        {
        ($InStuff[$Index..($Index + 2)]) -join ', '

        $InStuff[$Index + 1] = ''
        $InStuff[$Index + 2] = ''
        }
    }

$FromCSV = $CleanedInStuff |
    ConvertFrom-Csv

$FromCSV |
    Export-Csv -LiteralPath "$env:TEMP\Hobadee.csv" -NoTypeInformation

'=' * 40
$CleanedInStuff
'=' * 40
$FromCSV

屏幕输出...

========================================
name,address
John Doe,"123 Easy Way, Apt. 10, Somewhere, USA"
Jane Doe,"456 Main St, Unit 5, SomewhereElse, USA"
========================================

name     address                                
----     -------                                
John Doe 123 Easy Way, Apt. 10, Somewhere, USA  
Jane Doe 456 Main St, Unit 5, SomewhereElse, USA

CSV文件内容...

"name","address"
"John Doe","123 Easy Way, Apt. 10, Somewhere, USA"
"Jane Doe","456 Main St, Unit 5, SomewhereElse, USA"