TeeZee
TeeZee

Reputation: 171

Powershell CSV with headers to hashtable

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

Upvotes: 7

Views: 54724

Answers (7)

Mike Fisher
Mike Fisher

Reputation: 47

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

Upvotes: 2

Greg
Greg

Reputation: 81

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

Upvotes: 7

pernahajder
pernahajder

Reputation: 19

just specify a delimiter. in your case:

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

Upvotes: 1

llamb
llamb

Reputation: 329

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

Upvotes: 11

Jaykul
Jaykul

Reputation: 15824

just use the 2nd line as your header:

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

Upvotes: -1

JPBlanc
JPBlanc

Reputation: 72630

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.

Upvotes: 2

mjolinor
mjolinor

Reputation: 68273

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}
}

Upvotes: 1

Related Questions