Animesh D
Animesh D

Reputation: 5002

powershell hashtable problem

I am trying to read a config file which has some key value pairs as shown below:

age = 7
server = \\server\
destination = \\nas\public\server\

Here is the script I am using to read the file:

gc "keyval.txt" | % -begin {$h=@{}} -process { $k = [regex]::split($_,'='); if(($k[0].CompareTo("") -ne 0) -and ($k[0].StartsWith("[") -ne $True)) { $h.Add($k[0], $k[1]) } }
$h                    #THIS PRINTS THE KEYS and VALUES
$h.get_item("server") #THIS DOESN'T DO ANYTHING
$h.server             #THIS DOESNT DO ANYTHING AS WELL

I learnt that there are some oddities with hashtables in powershell, but could not get a hold on the way to avoid the oddities. Please help me resolve this issue.

Upvotes: 3

Views: 801

Answers (3)

mjolinor
mjolinor

Reputation: 68273

 $h = @{}
 gc keyval.txt |% {
 $h[$_.split("=")[0].trim()] = $_.split("=")[1].trim()
 }
 $h 
 $h.get_item("server")
 $h.server

 Name                                 Value                                                                                      
 ----                           -----                                                                                      
 age                            7                                                                                          
 server                         \\server\                                                                                  
 destination                    \\nas\public\server\                                                                       
 \\server\
 \\server\

Upvotes: 2

mjsr
mjsr

Reputation: 7590

first modify your txt to apply the method i'm going to teach you. Underground every string of the values part must be pass the c# interpretation so things like \s or \p are bad because they don't mean anything. So to have a backslash you need to escape it with backslash, example \\\\ means two backslash. After fix the file you must read all the content of the file and apply the convertfrom-stringdata cmdlet. Here is the code, enjoy.

>> $textfromfile = [IO.File]::ReadAllText((resolve-path .\keyval.txt))
>> $hash = ConvertFrom-StringData $textfromfile
>> $hash

Name                           Value
----                           -----
server                         \\server\
age                            7
destination                    \nas\public\server

PD: modify the file is one line

>> (gc .\keyval.txt) | % { $_ -replace '\\', '\\'} | Set-Content .\keyval.txt

Upvotes: 2

Keith Hill
Keith Hill

Reputation: 201652

If you don't want to modify the file:

$re = '\s*(\w+)\s*=\s*(\S+)'
Get-Content \temp\foo.txt | 
  Foreach {$ht=@{}} {if ($_ -match $re) {$ht.($matches[1]) = $matches[2]}} {$ht}

Name                           Value
----                           -----
age                            7
server                         \\server\
destination                    \\nas\public\server\

Upvotes: 3

Related Questions