我正在研究修改配置文件的powershell脚本。我有这样的文件:
#####################################################
# comment about logentrytimeout
#####################################################
Logentrytimeout= 1800
谁应该是这样的:
#####################################################
# comment about logentrytimeout
#####################################################
Logentrytimeout= 180
disablepostprocessing = 1
segmentstarttimeout = 180
如果存在密钥集(Logentrytimeout),只需将其更新为给定值即可。忽略注释,其中提到了键(以#开头的行)。密钥不区分大小写。
如果未设置密钥(disablepostprocessing和segmentstarttimeout),请将密钥和值附加到文件。到目前为止我的功能是这样的:
function setConfig( $file, $key, $value )
{
(Get-Content $file) |
Foreach-Object {$_ -replace "^"+$key+".=.+$", $key + " = " + $value } |
Set-Content $file
}
setConfig divider.conf "Logentrytimeout" "180"
setConfig divider.conf "disablepostprocessing" "1"
setConfig divider.conf "segmentstarttimeout" "180"
答案 0 :(得分:13)
假设您要替换的$key
始终位于一行的开头,并且它不包含特殊的正则表达式字符
function setConfig( $file, $key, $value ) {
$content = Get-Content $file
if ( $content -match "^$key\s*=" ) {
$content -replace "^$key\s*=.*", "$key = $value" |
Set-Content $file
} else {
Add-Content $file "$key = $value"
}
}
setConfig "divider.conf" "Logentrytimeout" "180"
如果没有替换$key = $value
将附加到文件中。
答案 1 :(得分:3)
如果需要,可以使用一些参数化和详细输出更新上述函数的版本。
Function Set-FileConfigurationValue()
{
[CmdletBinding(PositionalBinding=$false)]
param(
[Parameter(Mandatory)][string][ValidateScript({Test-Path $_})] $Path,
[Parameter(Mandatory)][string][ValidateNotNullOrEmpty()] $Key,
[Parameter(Mandatory)][string][ValidateNotNullOrEmpty()] $Value,
[Switch] $ReplaceExistingValue,
[Switch] $ReplaceOnly
)
$content = Get-Content -Path $Path
$regreplace = $("(?<=$Key).*?=.*")
$regValue = $("=" + $Value)
if (([regex]::Match((Get-Content $Path),$regreplace)).success)
{
If ($ReplaceExistingValue)
{
Write-Verbose "Replacing configuration Key ""$Key"" in configuration file ""$Path"" with Value ""$Value"""
(Get-Content -Path $Path) | Foreach-Object { [regex]::Replace($_,$regreplace,$regvalue) } | Set-Content $Path
}
else
{
Write-Warning "Key ""$Key"" found in configuration file ""$Path"". To replace this Value specify parameter ""ReplaceExistingValue"""
}
}
elseif (-not $ReplaceOnly)
{
Write-Verbose "Adding configuration Key ""$Key"" to configuration file ""$Path"" using Value ""$Value"""
Add-Content -Path $Path -Value $("`n" + $Key + "=" + $Value)
}
else
{
Write-Warning "Key ""$Key"" not found in configuration file ""$Path"" and parameter ""ReplaceOnly"" has been specified therefore no work done"
}
}
答案 2 :(得分:2)
我会这样做:
function setConfig( $file, $key, $value )
{
$regex = '^' + [regex]::escape($key) + '\s*=.+'
$replace = "$key = $value"
$old = get-content $file
$new = $old -replace $regex,$replace
if (compare-object $old $new)
{
Write-Host (compare-object $old $new | ft -auto | out-string) -ForegroundColor Yellow
$new | set-content $file
}
else {
$replace | add-content $file
Write-Host "$replace added to $file" -ForegroundColor Cyan
}
}
编辑:添加了一个替换铃,一个不匹配的口哨。
答案 3 :(得分:1)
将功能更改为:
function Set-Config( $file, $key, $value )
{
$regreplace = $("(?<=$key).*?=.*")
$regvalue = $(" = " + $value)
if (([regex]::Match((Get-Content $file),$regreplace)).success) {
(Get-Content $file) `
|Foreach-Object { [regex]::Replace($_,$regreplace,$regvalue)
} | Set-Content $file
} else {
Add-Content -Path $file -Value $("`n" + $key + " = " + $value)
}
}
然后,当您调用该函数时,请使用以下格式:
Set-Config -file "divider.conf" -key "Logentrytimeout" -value "180"
编辑:如果不存在,我忘记了添加该行的要求。这将检查$key
,如果存在,则会将其值设置为$value
。如果它不存在,它会将$key = $value
添加到文件的末尾。我还将该函数重命名为与power shell命名约定更加一致。
答案 4 :(得分:0)
@CarlR功能适用于PowerShell版本3.这适用于 PowerShell版本2 。
编辑:更改正则表达式以修复Set-FileConfigurationValue上的两个错误:
如果你有这样的一行:
; This is a Black line
你试着这样做:
Set-FileConfigurationValue $configFile "Black" 20 -ReplaceExistingValue
您收到一条关于“替换”的消息,但没有任何反应。
如果您有两条这样的行:
filesTmp = 50
TMP = 50
你试着这样做:
Set-FileConfigurationValue $configFile "Tmp" 20 -ReplaceExistingValue
你改变了两行!
filesTmp = 20 TMP = 20
这是最终版本:
Function Set-FileConfigurationValue()
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path $_})]
[string] $Path,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $Key,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string]$Value,
[Switch] $ReplaceExistingValue,
[Switch] $ReplaceOnly
)
$regmatch= $("^($Key\s*=\s*)(.*)")
$regreplace=$('${1}'+$Value)
if ((Get-Content $Path) -match $regmatch)
{
If ($ReplaceExistingValue)
{
Write-Verbose "Replacing configuration Key ""$Key"" in configuration file ""$Path"" with Value ""$Value"""
(Get-Content -Path $Path) | ForEach-Object { $_ -replace $regmatch,$regreplace } | Set-Content $Path
}
else
{
Write-Warning "Key ""$Key"" found in configuration file ""$Path"". To replace this Value specify parameter ""ReplaceExistingValue"""
}
}
elseif (-not $ReplaceOnly)
{
Write-Verbose "Adding configuration Key ""$Key"" to configuration file ""$Path"" using Value ""$Value"""
Add-Content -Path $Path -Value $("`n" + $Key + "=" + $Value)
}
else
{
Write-Warning "Key ""$Key"" not found in configuration file ""$Path"" and parameter ""ReplaceOnly"" has been specified therefore no work done"
}
}
我还添加了一个从配置文件中读取的功能
Function Get-FileConfigurationValue()
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path $_})]
[string] $Path,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $Key,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[string]$Default=""
)
# Don't have spaces before key.
# To allow spaces, use "$Key\s*=\s*(.*)"
$regKey = $("^$Key\s*=\s*(.*)")
# Get only last time
$Value = Get-Content -Path $Path | Where {$_ -match $regKey} | Select-Object -last 1 | ForEach-Object { $matches[1] }
if(!$Value) { $Value=$Default }
Return $Value
}
答案 5 :(得分:0)
function sed($filespec, $search, $replace)
{
foreach ($file in gci -Recurse $filespec | ? { Select-String $search $_ -Quiet } )
{
(gc $file) |
ForEach-Object {$_ -replace $search, $replace } |
Set-Content $file
}
}
用法:
sed ".\*.config" "intranet-" "intranetsvcs-"