您可以使用Get-Content 读取您的配置文件,并将每个名称下的部分内容存储在嵌套哈希表中,其中名称行是外部键,设置行分为键和值内部哈希表。为了保持从原始文件中找到的键的顺序,我们可以使用System.Collections.Specialized.OrderedDictionary。要创建一个,只需将[ordered] 属性添加到哈希表@{}。您可以通过about_Hash_Tables 了解更多信息。
我们还可以使用System.String.Split 将行分割为=,这将使用长度来确定该行是名称还是设置。长度 1 是名称,长度 2 是设置。
# Read lines from config file
$config = Get-Content -Path .\config.txt
# Use an ordered hashtable to remember order of keys inserted
$sections = [ordered]@{}
# Keep a key which indicates the current name being added
$currentKey = $null
# Go through each line in the config file
foreach ($line in $config) {
# Split each line by '='
$items = $line.Split("=")
# If splitted items is only one value, we found a new name
# Set the new name and create an inner settings dictionary
if ($items.Length -eq 1) {
$currentKey = $line
$sections[$currentKey] = [ordered]@{}
}
# Otherwise we found a normal line
else {
# Only add the setting if the current name is not null
if ($null -ne $currentKey) {
$sections[$currentKey][$items[0]] = $items[1]
}
}
}
这将给出一个哈希表$sections,如下所示:
Name Value
---- -----
{name1} {Settinga, settingb, settingc}
{name2} {Settinga, settingb, settingc}
{name3} {Settinga, settingb, settingc}
然后你可以像这样设置一个值(或多个值):
$sections["{name3}"].settingb = 4
并使用Out-File 将更新的哈希表写入输出文件。要迭代外部和内部哈希表,我们需要使用System.Collections.Hashtable.GetEnumerator 来迭代它们的键值对。
& {
# Output each outer key first, where the names are stored
foreach ($outerKvp in $sections.GetEnumerator()) {
$outerKvp.Key
# Then output each setting and value
foreach ($innerKvp in $outerKvp.Value.GetEnumerator()) {
"$($innerKvp.Key)=$($innerKvp.Value)"
}
}
# Pipe output from script block to output file
} | Out-File -FilePath .\output.txt
上面将foreach 循环包装在Call Operator & 中以运行脚本块并将输出通过管道传输到Out-File。您可以查看about_Pipelines 和about_Script_Blocks 了解更多信息。
由于我提到了管道和脚本块,我们还可以使用Foreach-Object 将输入传递到管道中。从一些初始测试来看,这似乎比上述解决方案稍慢(需要使用更大的输入进一步调查)。您可以查看这个Runtime of Foreach-Object vs Foreach loop 问题,了解两种方法之间的区别。
$sections.GetEnumerator() | ForEach-Object {
$_.Key
$_.Value.GetEnumerator() | ForEach-Object {
"$($_.Key)=$($_.Value)"
}
} | Out-File -FilePath .\output.txt
最后是下面新创建的输出文件。
output.txt
{name1}
Settinga=1
settingb=2
settingc=3
{name2}
Settinga=1
settingb=2
settingc=3
{name3}
Settinga=1
settingb=4
settingc=3
显示settingb 的{name3} 是从2 从4 更新的。