powershell 使用Lookuptable和Switch替换大文件中的多个字符串

ar5n3qh5  于 5个月前  发布在  Shell
关注(0)|答案(1)|浏览(40)

我在这里找到了一个解决方案:Scanning log file using ForEach-Object and replacing text is taking a very long time
但是,当Lookuptable中的字符串包含括号(())时,我遇到了一个错误。

$lookupTable = @{
  "Hello (1234)" = "new string 1"
  "Some'thing (2023)" = "other"
}

$inputfile = "c:\somewhere\*.*"

Get-ChildItem $inputfile -Filter *.txt | ForEach-Object {
  $outfile = Join-Path -Path "c:\else\" -ChildPath ('{0}{1}_new' -f $_BaseName, $_.Extension)
  $regexLookup = '({0})' -f (($lookupTable.Keys | ForEach-Object { [regex]::escape($_) }) -join '|')
  $writer = [System.IO.StreamWriter]::new($outfile, $true)

  Switch -regex -file $_ {
    $regexLookup {
      $line = $_
      $match = [regex]::Match($line, $regexLookup)
      while ($match.Success) {
        $line = $line -replace $match.Value, $lookupTable[[regex]::Unescape($match.Value)]
        $match = $match.NextMatch()
      }
      $writer.WriteLine($line)
    }
    default { $write.Writeline($_) }
  }

  $writer.flush()
  $writer.Dispose()
}

字符串
我得到的错误是:
正则表达式模式Hello(1234)无效。
在c:\wheremyfileis.ps1:.

  • $line = $line -替换$match.Value,$lookupTable[[regex.
pw9qyyiw

pw9qyyiw1#

你遇到的问题是因为括号是正则表达式中的特殊字符。当它们出现在你的查找键中时,它们被解释为搜索模式的一部分,导致错误。
你已经在你的脚本中使用了[regex]::escape($_),它应该在正则表达式中转义特殊字符,但这似乎不起作用。我对你的代码做了一些调整,它现在在我的机器上像预期的那样工作:

$lookupTable = @{
  "Hello (1234)" = "new string 1"
  "Some'thing (2023)" = "other"
}

$inputfile = "c:\somewhere\*.*"

Get-ChildItem $inputfile -Filter *.txt | ForEach-Object {
  $outfile = Join-Path -Path "c:\else\" -ChildPath ('{0}_new{1}' -f $_.BaseName, $_.Extension)
  $regexLookup = '({0})' -f (($lookupTable.Keys | ForEach-Object { [regex]::escape($_) }) -join '|')
  $writer = [System.IO.StreamWriter]::new($outfile, $true)

  Switch -regex -file $_ {
    $regexLookup {
      $line = $_
      $match = [regex]::Match($line, $regexLookup)
      while ($match.Success) {
        $escapedMatch = [regex]::Escape($match.Value)
        $line = $line -replace $escapedMatch, $lookupTable[$match.Value]
        $match = $match.NextMatch()
      }
      $writer.WriteLine($line)
    }
    default { $writer.Writeline($_) }
  }

  $writer.flush()
  $writer.Dispose()
}

字符串
我调整了-replace操作以使用$match.Value的转义版本,以确保匹配中的任何特殊字符都得到正确处理,并确保用于在$lookupTable中查找替换字符串的键是未转义的匹配值。最后,我更改了您的代码,因此文件扩展名保持不变,在最后一个句点之前追加了_new

相关问题