PowerShell从简单的.ini文件中读取单个值

Jus*_*ohn 5 powershell ini

我发现的一切看起来都很复杂.这几乎就像我只需要阅读一个文本文件.

ADAP.ini包含这个,没有别的:

http://xxx.104.xxx.226
APP=2.3.6
DLL=2.3.6
Run Code Online (Sandbox Code Playgroud)

使用Powershell,我如何阅读APP =值是什么?和/或DLL =值是什么?

我会将值存储在变量中,稍后在Powershell脚本中使用它.

Mar*_*agg 8

这看起来像一个很好的用例,ConvertFrom-StringData默认情况下查找由equals符号分隔的键值对.

因为.ini文件的第一行没有等于我们需要跳过它以避免错误.这可以简单地完成Select -Skip 1.

这是代码:

$ADAP = Get-Content 'ADAP.ini' | Select -Skip 1 | ConvertFrom-StringData
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过访问它们作为$ADAP对象的命名属性来获取APP和DLL的值,如下所示:

$ADAP.APP
$ADAP.DLL
Run Code Online (Sandbox Code Playgroud)

  • 这种方法是可行的,但在 Powershell 4 上,这会返回每个配置值的哈希表数组,而不是单个哈希表。编辑:弄清楚了。$configData = 获取内容-路径'refresh.ini'-Raw | 从字符串数据转换 (3认同)
  • 我见过很多针对此类问题的解决方案,但没有人提出如此优雅的解决方案。谢谢谢谢非常感谢! (2认同)

Dav*_*ant 6

您可以很容易地编写一个PowerShell函数,该函数可以读取ini文件:

function Get-IniFile 
{  
    param(  
        [parameter(Mandatory = $true)] [string] $filePath  
    )  

    $anonymous = "NoSection"

    $ini = @{}  
    switch -regex -file $filePath  
    {  
        "^\[(.+)\]$" # Section  
        {  
            $section = $matches[1]  
            $ini[$section] = @{}  
            $CommentCount = 0  
        }  

        "^(;.*)$" # Comment  
        {  
            if (!($section))  
            {  
                $section = $anonymous  
                $ini[$section] = @{}  
            }  
            $value = $matches[1]  
            $CommentCount = $CommentCount + 1  
            $name = "Comment" + $CommentCount  
            $ini[$section][$name] = $value  
        }   

        "(.+?)\s*=\s*(.*)" # Key  
        {  
            if (!($section))  
            {  
                $section = $anonymous  
                $ini[$section] = @{}  
            }  
            $name,$value = $matches[1..2]  
            $ini[$section][$name] = $value  
        }  
    }  

    return $ini  
}  

$iniFile = Get-IniFile .\ADAP.ini
$app = $iniFile.NoSection.APP
$dll = $iniFile.NoSection.DLL
Run Code Online (Sandbox Code Playgroud)

对于保存为Test.ini的此示例ini文件:

; last modified 1 April 2001 by John Doe
[owner]
name=John Doe
organization=Acme Widgets Inc.

[database]
; use IP address in case network name resolution is not working
server=192.0.2.62     
port=143
file="payroll.dat"
Run Code Online (Sandbox Code Playgroud)

这样做:

$testIni = Get-IniFile .\Test.ini
Run Code Online (Sandbox Code Playgroud)

允许您检索这样的值:

$server = $testIni.database.server
$organization = $testIni.owner.organization
Run Code Online (Sandbox Code Playgroud)

  • 这个非常有用。我对其进行了一些改进,并在此发布了结果:https://gist.github.com/beruic/1be71ae570646bca40734280ea357e3c。我还添加了一个 INI 编写器。 (2认同)

Tes*_*ler 6

你做“只需要读取一个文本文件”..然后找到哪一行以 APP 开头,然后从中提取值。

# read text file                        # find line beginning APP=
$AppLine = Get-Content -Path test.ini | Where-Object { $_ -match 'APP=' }

# split on = symbol and take second item
$AppVersion = $AppLine.Split('=')[1]
Run Code Online (Sandbox Code Playgroud)

你可能会受益于[version]$AppVersion将它变成一个适当的可排序的、可比较的版本号而不是一个字符串。

而且有很多的方法可以做到的阅读和匹配和值的提取(变异Get-Contentswitch -fileSelect-StringForEach-Object-match 'APP=(.*)',等各种组合)。

但总体而言,Mark Wragg 的回答更好。


Unk*_*ble 6

Mark Wragg 答案的稍微修改版本,在将其传递给 cmdlet 进行处理之前进行简单的检查以确保每一行都是有效的。

$Config = Get-Content "C:\scripts\config.ini" |
    Where-Object {$_ -match "="} | ConvertFrom-StringData
Run Code Online (Sandbox Code Playgroud)

只是在我自己登陆这里时添加它,并最终使用此解决方案来处理具有多个类别和注释行的配置文件。

编辑:

几年后,当我忘记自己以前是如何做到这一点时,我自己又不断地回到这个页面,所以我带着更多的润色回来了:

$Config = Get-Content $PSScriptRoot\config.txt |
    Where-Object { $_ -Match "=" } |
        ForEach-Object { $_ -Replace "#.*", "" } |
            ForEach-Object { $_ -Replace "\\", "\\" } |
                ConvertFrom-StringData
If ($Config.Target -Eq "Bob") { "The target is Bob." }
    Else { "The target is not Bob." }
Run Code Online (Sandbox Code Playgroud)

配置.txt:

# target = fred
target = Bob # this is the real target
you know, joe
Run Code Online (Sandbox Code Playgroud)


pan*_*mic 0

$content = Get-Content ADAP.ini

$app = $content[1].Substring($content[1].IndexOf("=") + 1)
$dll = $content[2].Substring($content[2].IndexOf("=") + 1)
Run Code Online (Sandbox Code Playgroud)

您可以通过调用 cmdlet Get-Content 并将其分配给变量来获取内容。通过访问数组中的索引等行,您可以调用处理字符串的方法。

注意:我知道代码很丑陋。