如何通过密钥获取ini文件值?

时间:2016-12-14 09:06:37

标签: powershell

所以我有ini file和解析我文件的函数:

Function Parse-IniFile ($file)
{
    $ini = @{}

    # Create a default section if none exist in the file. Like a java prop file.
    $section = "NO_SECTION"
    $ini[$section] = @{}

    switch -regex -file $file
    {
        "^\[(.+)\]$"
        {
            $section = $matches[1].Trim()
            $ini[$section] = @{}
        }

        "^\s*([^#].+?)\s*=\s*(.*)"
        {
            $name,$value = $matches[1..2]

            # skip comments that start with semicolon:
            if (!($name.StartsWith(";")))
            {
                $ini[$section][$name] = $value.Trim()
            }
        }
    }

    $ini
}

用法:

$iniFile = Parse-IniFile "myFile.ini"

因此,如果我的文件包含特定密钥,例如"blabla",我该如何获取值?

这就是我的尝试:

$value= $iniFile["blabla"]

2 个答案:

答案 0 :(得分:3)

解析INI文件会生成INI文件中各部分的哈希表,其中每个部分键的值是另一个哈希表,其中包含来自相应部分的键/值对。

基本上,这样的INI文件:

[something]
foo=23
bar=42

[other]
baz=5

成为这样的哈希表数据结构:

HWND activeWindow = GetForegroundWindow();
if (activeWindow)
{
    HBRUSH brush = CreateSolidBrush(RGB(0, 0, 0));                  
    SetClassLongPtr(activeWindow, GCLP_HBRBACKGROUND, (LONG)brush);

    InvalidateRect(activeWindow, NULL, TRUE);
    int redraw =  ::UpdateWindow(activeWindow);
}

要在嵌套哈希表中获取特定键的值,您需要做的是检查哪个嵌套哈希表包含该名称的键:

@{
  'something' = @{
    'foo' = 23
    'bar' = 42
  }
  'other' = @{
    'baz' = 5
  }
}

答案 1 :(得分:0)

在选择的哈希表数据模型中,您需要知道部分名称以确定给定属性键的属性值 ;这个数据模型如下:

$y = @{ 'sectionname' = @{ 'propertykey' = 'propertyvalue' } }

对于给定的属性键,您可以更直接地(我敢说第一手)访问属性值 反转哈希表数据模型

$x = @{ 'propertykey' = @{ 'sectionname' = 'propertyvalue' } }
下一个脚本代码段中的

Parse-FileIni函数显示了后者的可能实现(注释以便更好地理解):

Function Parse-FileIni ($file)
{
    Function add_ini ( $auxadd )
    {
        if ( -not $ini.ContainsKey($name) )
        {
            $ini[$name] = @{}
        }
        $ini[$name][$section] = $value.Trim()
        if ( $auxadd ) { $aux[$section]++ }
    }
    $ini = @{}                         # create output object
    $aux = @{}                         # create properties counter for sections
    $section = '[]'          # section default name for out-of-sectionproperties

    #switch -regex -file $file         # garbles ANSI characters above 0x7F
                         # works for (plain) ASCII, UTF-8 and files with BOM
    switch -regex ( Get-Content $file )# -Encoding Default (i.e. ANSI)
    {
        '^\[(.+)\]$'                   # [section]
        {
            $section = $matches[1].Trim()
            if ( -not $aux.ContainsKey( $section ) ) {
                $aux[ $section ] = [int] 0
            }

        }

        '^\s*([^#\[;].+?)\s*=\s*(.*)'  # 'name=value'; works as well for 'name='
        {
            $name,$value = $matches[1..2]
            add_ini $true
        }
        '^\s*([^;\[#][^=]+?)$'         # name (omitted '=' or '=value')
        {
            $name = $matches[1].Trim()
            $value = ''
            add_ini $true
        }
    }
    $name,$value = '',''               # add empty sections
    $aux.Keys | ForEach-Object { 
            if ( $aux[$_] -eq 0 ) { 
                $section = $_
                add_ini $false
            }
        }
    $ini                               # return an object
}

Function Parse-IniFile ($file)
{
    $ini = @{}
    # Create a default section if none exist in the file. Like a java prop file.
    $section = "_NO_SECTION"
    $ini[$section] = @{}
    #switch -regex -file $file         
    switch -regex  ( Get-Content $file )
    {
        '^\[(.+)\]$'
        {
            $section = $matches[1].Trim()
            if (-not $ini.ContainsKey($section)) { $ini[$section] = @{} }
        }

        '^\s*([^#\[;].+?)\s*=\s*(.*)'
        {
            $name,$value = $matches[1..2]
            $ini[$section][$name] = $value.Trim()
        }
        '^\s*([^;\[#][^=]+?)$'
        {
            $name = $matches[1].Trim()
            $value = ''
            $ini[$section][$name] = $value.Trim()
        }
    }
    $ini
}

'-iniFile-'

$iniFile = ''
$iniFile = Parse-IniFile "d:\test\Google.ini"
$iniFile | Format-Table -AutoSize -Wrap

'-iniFili-'

$iniFili = ''
$iniFili = Parse-FileIni "d:\test\Google.ini"
$iniFili

我对正确解析我的测试Parse-IniFile文件所需的原始.ini函数进行了一些更改;用于解释上述脚本和下一个Google.ini文件中的注释:

; PSPad configuration file for Google interface - adapted for testing
;; fake properties out of sections
foo="bar"
bubu=
; Search only pages in selected language
[Language]
Czech=lang_cz
English=lang_en
;; misunderstood (fake) use 
UK=English
; For search use selected Google server
[GoogleServer]
Česká Republika=www.google.cz
Österreich=www.google.at
UK=www.google.co.uk
;; multiple section declaration: simply merge their properties together
[Language]
German=lang_de
;; second occurrence of a property name: discard and override the first occurrence
Czech=lang_cs
;; fake empty section - somewhere in middle
[Client]
; Search only selected server
[ServerSearch]
;; only keys, no values, missing or present =
pspad.com
php.net=
w3.org
;; fake empty section - at the foot of file 
[Protocol]

输出显示差异

PS D:\PShell> D:\PShell\SO\41138597_Parse-IniFile.ps1
-iniFile-
Name         Value                            
----         -----                            
_NO_SECTION  {bubu, foo}              
GoogleServer {UK, Česká Republika, Österreich}
Client       {}                               
Language     {English, German, UK, Czech}     
ServerSearch {w3.org, pspad.com, php.net}     
Protocol     {}                               

-iniFili-
Name            Value                   
----            -----                   
bubu            {[]}                    
UK              {GoogleServer, Language}
Czech           {Language}              
w3.org          {ServerSearch}          
php.net         {ServerSearch}          
Österreich      {GoogleServer}          
English         {Language}              
Česká Republika {GoogleServer}          
German          {Language}              
foo             {[]}                    
pspad.com       {ServerSearch}          
                {Client, Protocol}      

PS D:\PShell> $iniFili['UK']
Name                           Value                                                      
----                           -----                                                      
GoogleServer                   www.google.co.uk                                           
Language                       English                                                    

PS D:\PShell> $iniFili['UK']['GoogleServer']
www.google.co.uk