2013-03-27 2 views
5

私は設定ファイルを変更するpowershellスクリプトで作業しています。キーセット(Logentrytimeout)、ただ与えられた値に更新があった場合Powershellはテキストファイルの行を置換または追加する機能を持っています

##################################################### 
# comment about logentrytimeout 
##################################################### 
Logentrytimeout= 180 
disablepostprocessing = 1 
segmentstarttimeout = 180 

:次のようになります。

##################################################### 
# comment about logentrytimeout 
##################################################### 
Logentrytimeout= 1800 

:私はこのようなファイルを持っています。キーが記述されているコメント(#で始まる行)は無視してください。キーは大文字と小文字を区別しません。

キーが設定されていない(disablepostprocessingおよびsegmentstarttimeout)場合は、キーと値をファイルに追加します。 My機能は、これまでのところ、このように書きます:

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" 
  • 正しい正規表現とは何ですか?
  • 置き換えがあるかどうかを確認するにはどうすればよいですか?
  • 置き換えがない場合:$ key + "=" + $ valueをファイルに追加するにはどうしたらいいですか?

答えて

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 
     } 

} 

編集を:交換用の鐘を追加し、笛と一致しません。

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を追加します。また、関数の名前をパワーシェルの命名規則と一貫して変更しました。 $key置き換えたいが、行の先頭に常にあり、そして$key = $valueがファイルに追加されます代替はありませんが存在しない場合、それは

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" 

を特別な正規表現文字が含まれていないと仮定すると

3

必要に応じて、いくつかのパラメータと冗長な出力を持つ上記の関数のバージョンを更新しました。それはPowerShellのバージョン2に適応同じだPowerShellのバージョン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" 
    } 
} 
0

@CarlR機能。

EDIT:あなたはこのような1行がある場合

  1. ; This is a Black line

    をそして、あなたがやろうセットFileConfigurationValue上の2つのバグを修正するために変更の正規表現:

    Set-FileConfigurationValue $configFile "Black" 20 -ReplaceExistingValue

    「交換」についてのメッセージが表示されますが、何も起こりません。

  2. あなたはこれらのような二行がある場合:

    filesTmp = 50
    のTmp = 50

    をそして、あなたがやろう:

    Set-FileConfigurationValue $configFile "Tmp" 20 -ReplaceExistingValue

    あなたが変更の2行を取得!

    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" 
    } 
} 

は、私はまた、configファイルからの読み取りに機能を追加しました

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 
} 
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-" 
関連する問題