Answered by:
Convert a 2 columns CSV into a hash table

Question
-
Hi,
have a CSV file, with 2 columns, and 35 records. It is a correspondence table
Source, Destination
S1,D1
S2,D1
S3,D2
S4,D4
....My way to look for the corresponding value is
$loc=import-csv table.csv
($loc | ? {$_.Source -eq 'S1'}).Destination
It works, but I'm sure it is not that efficient, and it looks kind of ugly.
Is there a way to import the CSV into a hast table, I would like to be able to do:
$a['S1'] returns D1
$a['S4'] returns D4Thank you
Friday, January 28, 2011 1:27 AM
Answers
-
Sorry about that. Convertfrom-stringdata is normally used with here-strings, and is expecting a newline between each element. This should work better:
$HashTable = ((get-content table.csv) -replace ",","=") -join "`n" | convertfrom-stringdata
$hashtable.remove("Oracle")
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "- Marked as answer by Cyreli Friday, January 28, 2011 7:02 PM
Friday, January 28, 2011 5:49 PM -
I assume that your csv does not contani header row, so below code should work:
$t = Import-Csv -Path C:\CompanyData\tmp\t.csv -Header "column1","column2" $HashTable = @{} foreach($r in $t) { Write-Host $r.column1 $r.column2 $HashTable[$r.column1] = $r.column2 } $HashTable
With kind regards
Krystian Zieja
http://www.projectnenvision.com
Follow me on twitter
My Blog- Marked as answer by Cyreli Friday, January 28, 2011 4:25 AM
Friday, January 28, 2011 3:04 AM -
Another option if you have Powershell V2 is to use get-content, replace the commas with equal signs, and use convertfrom-stringdata.
$HashTable = @(get-content table.csv) -replace ",","=" | convertfrom-stringdata
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "- Marked as answer by Cyreli Friday, January 28, 2011 4:25 AM
Friday, January 28, 2011 4:07 AM
All replies
-
I assume that your csv does not contani header row, so below code should work:
$t = Import-Csv -Path C:\CompanyData\tmp\t.csv -Header "column1","column2" $HashTable = @{} foreach($r in $t) { Write-Host $r.column1 $r.column2 $HashTable[$r.column1] = $r.column2 } $HashTable
With kind regards
Krystian Zieja
http://www.projectnenvision.com
Follow me on twitter
My Blog- Marked as answer by Cyreli Friday, January 28, 2011 4:25 AM
Friday, January 28, 2011 3:04 AM -
Another option if you have Powershell V2 is to use get-content, replace the commas with equal signs, and use convertfrom-stringdata.
$HashTable = @(get-content table.csv) -replace ",","=" | convertfrom-stringdata
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "- Marked as answer by Cyreli Friday, January 28, 2011 4:25 AM
Friday, January 28, 2011 4:07 AM -
Thank you to both of you.
First time I heard from ConvertFrom-Stringdata
Friday, January 28, 2011 4:25 AM -
$HashTable = @(get-content table.csv) -replace ",","=" | convertfrom-stringdata
My CSV file as a header
so
$hastable returns:
Name Value
---- -----
ORACLE AD
Australia AU-RemoteMy goal is to remove then the first element with
$hastable.remove("ORACLE") but I got this
Method invocation failed because [System.Object[]] doesn't contain a method named 'remove'.
$hastable | gm returns
PS C:\Docs> $hastable| gm
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Add Method System.Void Add(System.Object key, System.Object value)
Clear Method System.Void Clear()
Clone Method System.Object Clone()
Contains Method bool Contains(System.Object key)
ContainsKey Method bool ContainsKey(System.Object key)
ContainsValue Method bool ContainsValue(System.Object value)
CopyTo Method System.Void CopyTo(array array, int arrayIndex)
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator GetEnumerator()
GetHashCode Method int GetHashCode()
GetObjectData Method System.Void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
GetType Method type GetType()
OnDeserialization Method System.Void OnDeserialization(System.Object sender)
Remove Method System.Void Remove(System.Object key)
ToString Method string ToString()
Item ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count Property System.Int32 Count {get;}
IsFixedSize Property System.Boolean IsFixedSize {get;}
IsReadOnly Property System.Boolean IsReadOnly {get;}
IsSynchronized Property System.Boolean IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
Friday, January 28, 2011 4:48 PM -
Sorry about that. Convertfrom-stringdata is normally used with here-strings, and is expecting a newline between each element. This should work better:
$HashTable = ((get-content table.csv) -replace ",","=") -join "`n" | convertfrom-stringdata
$hashtable.remove("Oracle")
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "- Marked as answer by Cyreli Friday, January 28, 2011 7:02 PM
Friday, January 28, 2011 5:49 PM -
That did fix the issue.
Anyway why is the "hasttable" is correctly populated with
$HashTable = @(get-content table.csv) -replace ",","=" | convertfrom-stringdata
but not seen as a "real" hashtable ?
Friday, January 28, 2011 5:54 PM -
It was actually an array of hashtables, each with one element.
Powershell's tendency to "unroll" arrays when you display them was covering up the fact that it it was an array, making it look like one hashtable.
$hashtable["Oracle"] wouldn't return anything.
$hashtable[0]["Oracle"] would return "AD", but that's all that was in that hashtable.
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "Friday, January 28, 2011 5:59 PM