Powershell搜索和替换以忽略以#开头的行

时间:2013-05-06 17:13:40

标签: regex powershell

我有这样的配置文件:

servername = 127.0.0.1
serverport = 44101
servername = 127.0.0.1
serverport = 0
#serverport = 44102

到目前为止,我有一个替换端口号的函数:

# Replace Ports. Syntax:  Oldport=Newport
$WorkerPorts = @{44101=44201; 44102=44202; 44103=44203; 44104=44204}

function replacePort( $file, $Portarray )
{
  Write-Host "Replacing Ports in $file"

  foreach ($p in $Portarray.GetEnumerator())
  {
    Write-Host "  Replace Port $($p.Name) with $($p.Value) ... " -NoNewLine

    (Get-Content $file) | 
    Foreach-Object {$_ -replace $($p.Name), $($p.Value)} | 
    Set-Content $file

    Write-Host "Done"
  }
}

$DividerConf = "$strPath\divider\conf\divider.conf"
replacePort $DividerConf $WorkerPorts

但是,这也会替换已注释掉的端口(以#开头的行)。该函数应如何仅替换不以#开头的行?我在考虑类似的事情:

function replacePort( $file, $Portarray )
{
  Write-Host "Replacing Ports in $file"

  foreach ($p in $Portarray.GetEnumerator())
  {
    if ( $content -match "^[^#]*$($p.Name)*" )
    {
      Write-Host "  Replace Port $($p.Name) with $($p.Value) ... " -NoNewLine

      (Get-Content $file) | 
      Foreach-Object {$_ -replace $($p.Name), $($p.Value)} | 
      Set-Content $file

      Write-Host "Done"
    }
  }
}

但我无法弄清楚正确的正则表达式。

修改 好的,这就是我要做的:从

更改配置文件中的端口
servername = 127.0.0.1
serverport = 44101
servername = 127.0.0.1
serverport = 0
#serverport = 44102

servername = 127.0.0.1
serverport = 44201
servername = 127.0.0.1
serverport = 0
#serverport = 44102

使用上面的PowerShell函数:

# Replace Ports. Syntax:  Oldport=Newport
$WorkerPorts = @{44101=44201; 44102=44202; 44103=44203; 44104=44204}
$DividerConf = "$strPath\divider\conf\divider.conf"

function replacePort( $file, $Portarray )
{
  #Here I need your help :)
}

replacePort $DividerConf $WorkerPorts

@Trevor:到目前为止,我通常会展示我的解决方案。否则我认为我要求你做我的工作;)

2 个答案:

答案 0 :(得分:3)

与Trevor相同,但在路上进行评论检查。

Foreach ($line in (Get-Content -Path $configFile | Where {$_ -notmatch '^#.*'})) 
{ 
    Foreach ($Port in $PortMapping.Keys) 
    { ... }
}

如果您还想跳过任何空白行,请将Get-Content中的Where更改为

Where { $_ -notmatch '^#.*' -and $_ -notmatch '^\s*$' } 

答案 1 :(得分:1)

我认为这样的事情会起作用,虽然它当然也不是最有效的选择。基本上,你:

  1. 遍历conf文件的每一行
  2. 对于文件中的每一行,迭代PortMapping中的每个端口
  3. 对于PortMapping中的每个端口,执行替换,然后将该行写入目标文件
  4. <强>代码

    $PortMapping       = @{
                          44101 = 44201;
                          44102 = 44202;
                          44103 = 44203;
                          44104 = 44204;
                          };
    
    $ConfigSource      = Get-Content -Path $PSScriptRoot\divider.conf;
    $ConfigDestination = $PSScriptRoot\divider2.conf;
    
    foreach ($Line in $ConfigFile) {
        if ($Line -notmatch '\#') {
            foreach ($Port in $PortMapping.Keys) {
                $Line = $Line.Replace($Port, $PortMapping[$Port]);
                Add-Content -Path $ConfigDestination -Value $Line;
            }
        }
    }