7

I have a csv file with a header row and I want to convert it to a Hashtable.

For example, this is my input:

#Version1.0
#Fields:ID,Data
1,data1
2,data2
3,data3

I want the output to be a hashtable where Key=ID and Value =Data.

This is what I have, but the results aren't quite what I want.

$mytable = Import-Csv -Path $filePath -Header ID,Data
$HashTable=@{}
foreach($r in $mytable)
{
    $HashTable[$r.ID]=$r.Data
}

This creates my table, but when I output it later via $str = $Hashtable | Out-String Write-Host $str

I'm getting the following:

Name                  Value
--------              -----------
#Fields:ID            Data
1                     data1
2                     data2
3                     data3

How do I get rid of the Headers being written to my hashtable? Is there a more elegant solution than sticking if ($r.ID.StartsWith("#")) { continue; }?

Thanks! -C

7 Answers 7

11

The default behavior in Import-Csv is to use the first (un-commented) line as the headers. Instead of defining the header in the command, remove "#Fields:" from the header line.

#Version1.0
ID,Data
1,data1
2,data2
3,data3

Then you can create the hashtable like this:

$mytable = Import-Csv -Path $filePath
$HashTable=@{}
foreach($r in $mytable)
{
    $HashTable[$r.ID]=$r.Data
}

Which returns:

Name                           Value
----                           -----
2                              data2
1                              data1
3                              data3
Sign up to request clarification or add additional context in comments.

Comments

7
$HashTable = @{}
Import-Csv $filePath | % { $HashTable[$_.ID] = $_.Data }

1 Comment

For the low cost of knowing the headers in the CSV file, this snippet does exactly what I need it to do!
3

Following down @llamb's road of using the first data line as headers, I had luck with:

PS> $mytable = Import-CSV -Path $filePath | Group-Object -AsHashTable -Property "ID"

PS> $mytable["2"]

ID Data
-- ----
2  data2

PS> $mytable["2"].Data
data2

Comments

2

You can try this :

Get-Content $filePath | where {$_ -notmatch '^#'} | ConvertFrom-Csv -Header ID,Data

It remove all the lines begining with # before readingg then as CSV lines.

1 Comment

I considered that, but it's not going to get you a hash table.
1

Don't know if it's "more elegant", but:

$mytable = Import-Csv -Path $filePath -Header ID,Data
$HashTable=@{}
foreach($r in $mytable)
{
    if ($r.ID -notlike '#*')
     {$HashTable[$r.ID]=$r.Data}
}

Comments

0

just specify a delimiter. in your case:

$mytable = Import-Csv -Path $filePath -Delimiter ","

1 Comment

That creates an array of objects with two properties, not a hashtable.
-1

just use the 2nd line as your header:

ipcsv .\test.csv | % { $o = @{}} { $o[$_."#Fields:ID"] = $_.Data } {$o}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.