在配置文件powershell或批处理文件中查找和替换[关闭]
Posted
技术标签:
【中文标题】在配置文件powershell或批处理文件中查找和替换[关闭]【英文标题】:Find and replace in config file powershell or batch file [closed] 【发布时间】:2020-08-22 22:03:45 【问题描述】:假设我有一个如下所示的配置文件:
name1
Settinga=1
settingb=2
settingc=3
name2
Settinga=1
settingb=2
settingc=3
name3
Settinga=1
settingb=2
settingc=3
我希望能够将 name3 下的行 settingb=2 更改为另一个值,例如 settingb=4
它将是 Windows 操作系统上的文件存储,因此理想情况下它可以在 PowerShell 或批处理命令下完成。
任何人有任何想法或者这是否可能?
谢谢
【问题讨论】:
你试过什么?在批处理中,您可以使用=
作为分隔符并跟踪每一行的值,如果它是name3
请注意,本网站不是免费的代码/脚本编写服务,而是特定编程相关问题和答案的资源!请(重新)参加tour,访问help center 并在此处了解How to Ask!也请转至minimal reproducible example!
【参考方案1】:
您可以使用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
更新的。
【讨论】:
以上是关于在配置文件powershell或批处理文件中查找和替换[关闭]的主要内容,如果未能解决你的问题,请参考以下文章