在Windows

时间:2016-10-14 17:10:08

标签: string perl powershell replace

包含150,000个文件的源文件夹,在Win 2003服务器中大小约为4 GB。需要递归替换XML文件中的少数模式。

$files = Get-ChildItem "source_folder" -Filter *.xml -Recurse
Write-Host $files.count "files present in source" 
foreach ($file in $files) {
      (Get-Content $file.PSPath) | 
          Foreach-Object { $_ -replace "string1", "replacement1" } | Foreach-Object { $_ -replace "string2", "replacement2" } | Set-Content $file.PSPath  
       Write-Host $file.PSPath " modified" 
}

此代码需要一个多小时才能完成。实现这一目标的最佳方法是什么?减少所用时间有哪些选择?使用PERL更好吗?建议会有很大的帮助!

4 个答案:

答案 0 :(得分:1)

你可以使用perl one-liner - 类似于:

perl -p -i -e 's/oldstring/newstring/g' `grep -ril --include *.xml oldstring *`

如果您想保留原始文件的备份:

perl -p -i'.bak' -e 's/oldstring/newstring/g' `grep -ril --include *.xml oldstring *`

答案 1 :(得分:1)

首先,您应该使用.NET Classes。 仅此一项就可以为您节省大量时间。你真的应该使用v3版本替换(.replace方法)。它更快。

所以它看起来像这样:

foreach ($file in $files) {
      $content = [System.IO.File]::ReadAllText($file).Replace("val1","val2")
    [System.IO.File]::WriteAllText($file, $content) 
       Write-Host $file.PSPath " modified" 
}

答案 2 :(得分:1)

尝试像这样修改你的代码:

    $files = Get-ChildItem "C:\temp" -Filter *.xml -Recurse -File
    foreach ($file in $files) 
    {

    (Get-Content $file.FullName) | Foreach-Object {
        $_ -replace 'something1', 'something1aa' `
           -replace 'something2', 'something2bb' `
           -replace 'something3', 'something3cc' `
           -replace 'something4', 'something4dd' `
           -replace 'something5', 'something5dsf' `
           -replace 'something6', 'something6dfsfds'
        } | Set-Content $file.FullName

        Write-Host $file.FullName " analysed" 
    }

答案 3 :(得分:-1)

虽然我没有相同的资源来测试这个,但我怀疑如果你避免这么多管道会运行得更快,如下:

$files = Get-ChildItem "source_folder" -Filter *.xml -Recurse
Write-Host $files.count "files present in source" 
foreach ($file in $files) {
    $s = Get-Content $file.PSPath
    $s = $s -replace "string1", "replacement1") -replace "string2", "replacement2" 
    Set-Content $file.PSPath  -Value $s
    Write-Host $file.PSPath " modified" 
}

管道机制有一些应该避免的开销。我很想知道它对你的案子有多大的不同。

另外一点,可能最好在Set-Content命令中添加-Encoding值来控制输出文件的编码方式。