I'm importing a CSV generated by the chess cli tool Ordo. It has this output format:
"#","PLAYER","RATING","ERROR","POINTS","PLAYED","(%)"
1,"New",2500.0,"-",841.50,1683,50.00
2,"Old",2500.0,"-",841.50,1683,50.00
I'm trying to import it in PowerShell 7 with this command:
$csv = Import-Csv -Path ./ratings.csv
$csv
1 : 2
New : Old
2500.0 : 2500.0
- : -
841.50 : 841.50
1683 : 1683
50.00 : 50.00
It seems to have done something really strange with the parsing. Instead of mapping the #, PLAYER, etc. columns as properties on the PSCustomObject, it's skipped the header row and interpreted the first data row as a header, then mapped the second row's values to those headers.
PowerShell 5.1 behavior
Curiously, this works fine on PowerShell 5.1:
$csv = Import-Csv C:\code\Forklift\matches\ratings.csv
$csv
# : 1
PLAYER : New
RATING : 2500.0
ERROR : -
POINTS : 841.50
PLAYED : 1683
(%) : 50.00
# : 2
PLAYER : Old
RATING : 2500.0
ERROR : -
POINTS : 841.50
PLAYED : 1683
(%) : 50.00
What I think is happening
Reading the documentation for Import-Csv for PowerShell 7, I find this line:
Import-Csvalso supports the W3C Extended Log format. Lines starting with the hash character (#) are treated as comments and ignored unless the comment starts with#Fields:and contains delimited list of column names. In that case, the cmdlet uses those column names. This is the standard format for Windows IIS and other web server logs. For more information, see Extended Log File Format.
That same section about comments is missing from the documentation for Import-Csv for PowerShell 5.1.
I suspect that the first field "#" is being interpreted as a W3C Extended Log format comment and destroying the header.
What's the solution here to correctly use Import-Csv when one of the header values is "#"?
#denotes a comment line, see Handle comments. So this is not a PowerShell issue per se. In other words you will see this crop up elsewhere. Your best bet is not start a line with#.#, the line starts with". This is a bug in PowerShell, it first parses the header into a list of values ("#","PLAYER"becomes@('#', 'PLAYER')) and then checks if the first parsed value is#. This is different from what the PowerShell docs say, which is that "Lines starting with the hash character (#) are treated as comments and ignored". Note the difference between checking the first parsed header value and the first character of the raw line.#vs"#"is really not a difference, you are starting a line with a text#in either case. Good luck though on your attempt.