尝试编辑文件的这一行(“VoIP.Enabled”1“)。我想将1更改为零。当我用
更改它时$dewprefs = Get-Content .\dewrito_prefs.cfg
$dewprefs | Select-String "VoIP.Enabled" | ForEach-Object {$_ -replace "1","0"} | Set-Content .\dewrito_prefs.cfg}`
然而,当我使用这个脚本时,它会移除100个其他行,编辑右边的行,然后删除其他所有内容,只留下我想编辑的行。
对此事的任何帮助都将受到高度赞赏
答案 0 :(得分:2)
Select-String
充当过滤器:也就是说,只有匹配模式时,才会传递给定的输入。
因此,仅将感兴趣的行写入输出文件。
如果所有输入行 - 尽管可能已修改 - 应该通过,请不要使用Select-String
;仅使用 ForEach-Object
,并且有条件地修改每个输入行:
$dewprefs = Get-Content .\dewrito_prefs.cfg
$dewprefs |
ForEach-Object { if ($_ -match 'VoIP\.Enabled') { $_ -replace '1', '0' } else { $_ } } |
Set-Content .\dewrito_prefs.cfg
$_ -match 'VoIP\.Enabled'
现在执行Select-String
在原始命令中执行的操作:仅当手头的输入行包含文字VoIP.Enabled
时才会匹配(请注意.
如何转义为\.
以确保在正则表达式的上下文中将其视为文字。
注意if
语句的两个分支如何产生输出:
$_ -replace '1', '0'
输出使用1
0
的所有实例的结果
$_
只是按原样传递输入行。
然而,最有可能的是,您可以使用单个if
表达式替换-replace
语句,并且假设该文件足够小以便作为整体读取(很可能,在配置文件),您可以使用Stu's helpful simplification的变体。
充分利用-replace
支持正则表达式(正则表达式)的事实,代码可以仅基于密钥名称(例如VoIP.Enabled
)更新行,而无需知道密钥的当前值。
$key = 'VoIP.Enabled'
$newValue = '1'
# Construct a regex that matches the entire target line.
$regex = '^\s*' + [regex]::Escape($key) + '\b.*$'
# Build the replacement line.
$modifiedLine = "$key $newValue"
(Get-Content .\dewrito_prefs.cfg) -replace $regex, $modifiedLine | Set-Content .\dewrito_prefs.cfg
请注意,将输出写回输入文件只能起作用,因为输入文件作为一个整体,在前面被读入内存,因为Get-Content
调用了(...)
1}}。
答案 1 :(得分:2)
这也适用于PowerShell v3 +,并且更简洁:
(Get-Content .\dewrito_prefs.cfg).replace('"VoIP.Enabled "1"', '"VoIP.Enabled "0"') |
Set-Content .\dewrito_prefs.cfg
你的报价有点奇怪(总共3个双引号?),但我已经模仿了你所问的内容。