PowerShell 从简单的 .ini 文件中读取单个值
Posted
技术标签:
【中文标题】PowerShell 从简单的 .ini 文件中读取单个值【英文标题】:PowerShell to Read single value from simple .ini file 【发布时间】:2017-09-27 04:05:21 【问题描述】:我发现的一切看起来都过于复杂。 这几乎就像我只需要阅读一个文本文件。
ADAP.ini 包含这个,仅此而已:
http://xxx.104.xxx.226
APP=2.3.6
DLL=2.3.6
使用 Powershell, 我如何阅读 APP=value 是什么? 或者 DLL=value 是什么?
我会将值存储在一个变量中,稍后在 Powershell 脚本中使用它。
【问题讨论】:
【参考方案1】:您可以很容易地编写一个允许您读取 ini 文件的 PowerShell 函数:
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
对于这个保存为 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"
这样做:
$testIni = Get-IniFile .\Test.ini
允许您像这样检索值:
$server = $testIni.database.server
$organization = $testIni.owner.organization
该代码的灵感来自一篇文章 here。
【讨论】:
这个非常有用。我对其进行了一些改进,并在此处发布了结果:gist.github.com/beruic/1be71ae570646bca40734280ea357e3c。我还包括了一个 INI 编写器。 您应该感谢该函数的原作者。 devblogs.microsoft.com/scripting/… @JohnC 不记得我在那里拿了那个代码,但你是对的:学分到期。【参考方案2】:Mark Wragg 答案的略微修改版本,在将每行传递给 cmdlet 进行处理之前进行简单检查以确保每行有效。
$Config = Get-Content "C:\scripts\config.ini" |
Where-Object $_ -match "=" | ConvertFrom-StringData
当我自己登陆这里并最终使用此解决方案来处理具有多个类别和注释行的配置文件时添加它。
【讨论】:
【参考方案3】:你做“只需要读取一个文本文件”..然后找到哪一行以 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]
您可能会从[version]$AppVersion
中受益,将其转换为适当的可排序、可比较的版本号,而不是字符串。
您可以通过多种方式读取、匹配和提取值(Get-Content
、switch -file
、Select-String
、ForEach-Object
、-match 'APP=(.*)'
等各种组合)。
但总体而言,Mark Wragg 的回答更好。
【讨论】:
【参考方案4】:这看起来像是 ConvertFrom-StringData
的一个很好的用例,默认情况下会查找由等号分隔的键值对。
由于 .ini 文件的第一行没有等号,我们需要跳过它以避免错误。这可以通过Select -Skip 1
轻松完成。
代码如下:
$ADAP = Get-Content 'ADAP.ini' | Select -Skip 1 | ConvertFrom-StringData
然后,您可以通过将它们作为$ADAP
对象的命名属性访问来获取 APP 和 DLL 的值,如下所示:
$ADAP.APP
$ADAP.DLL
【讨论】:
这种工作,但在 Powershell 4 上,这将返回一个哈希表数组,每个配置值而不是单个哈希表。编辑:想通了。 $configData = 获取内容 -Path 'refresh.ini' -Raw | ConvertFrom-StringData 我见过很多针对此类问题的解决方案,但没有人提出过如此优雅的解决方案。谢谢,非常感谢! 使用 Powershell 5.1,这种方法非常有弹性。空行和 cmets 似乎都被正确忽略了。根据我的经验,| Select -Skip 1
不是必需的。除了命名属性,您可能会发现您可以像这样按名称引用值:$ADAP["APP"]
或 $ADAP['DLL']
【参考方案5】:
$content = Get-Content ADAP.ini
$app = $content[1].Substring($content[1].IndexOf("=") + 1)
$dll = $content[2].Substring($content[2].IndexOf("=") + 1)
您可以通过调用 cmdlet Get-Content 并将其分配给变量来获取内容。通过访问数组中的索引之类的行,您可以调用处理字符串的方法。
注意:我知道代码很丑。
【讨论】:
谨慎假设值将在固定行!而是 sls以上是关于PowerShell 从简单的 .ini 文件中读取单个值的主要内容,如果未能解决你的问题,请参考以下文章