Powershell: ConvertFrom-Csv multiline entries

Created on 2 May 2018  路  6Comments  路  Source: PowerShell/PowerShell

CSV supports multiline entries with quoting escaping.
When a file is streamed as a collection of strings and not a single one, it will result in incorrect treating of such entries.

Steps to reproduce

  1. create a test.csv file with the following content
a,b
"1
2
3",x
cat ./test.csv | ConvertFrom-Csv

Expected behavior

a     b
-     -
1...  x

This is the output of cat ./test.csv -Raw | ConvertFrom-Csv

Actual behavior

a b
- -
1 
2 
3 x

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.1.0-preview.1
PSEdition                      Core
GitCommitId                    v6.1.0-preview.1
OS                             Darwin 17.5.0 Darwin Kernel Version 17.5.0: Mon Mar  5 22:24:32 PST 2018; root:xnu-4570.51.1~1/RELEASE_X...
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets-Utility

All 6 comments

$PSVersionTable.GetEnumerator() | Select-Object -Property name , value | Export-Csv -Encoding UTF8 -Delimiter ';' -Path C:\file1.csv -NoTypeInformation -Append

Import-Csv -Path C:\file1.csv -Delimiter ';' |Select-Object -Property *

@mbaju: What is your example meant to demonstrate? Note that Import-Csv is not affected by the bug.

Just to add some additional information regarding the incorrect behavior:

ConvertFrom-Csv currently blindly converts _each line_ of one-line-at-a-time input (from an array of strings or Get-Content without -Raw) into an object, which breaks with data rows that span multiple lines.

In the case at hand you therefore get _3_ output objects; the equivalent of (also note the inconsistent treatment of "):

[pscustomobject] @{
  a = '1'
  b = $null
},

[pscustomobject] @{
  a = '2'
  b = $null
},

[pscustomobject] @{
  a = '3"'
  b = 'x'
}

instead of the expected _single_ object:

[pscustomobject] @{
  a = "1`n2`n3"
  b = 'x'
}

@vors So doing Get-Content -Raw works properly?

@BrucePay: Yes, it does, given that a scalar multi-line string works too:

@'
a,b
"1
2
3",x
'@ | ConvertFrom-Csv | Measure-Object

The above yields a count of 1, as expected.

@BrucePay yes, as @mklement0 mentioned. But there should not be the semantical difference imo.

Using Get-Content -Raw doesn't work in a particular circumstance where this problem is affecting me:

gc -wait postgresql-2020-02-10_182428.csv | ConvertFrom-Csv -Header $csvHeader -Delimiter ','

The -Raw flag on Get-Content cannot be used with -Wait.

Was this page helpful?
0 / 5 - 0 ratings