我有一個CSV文件中的字符串列表。格式爲:使用Powershell替換多個文件和文件夾中的多個字符串
OldValue,NewValue
223134,875621
321321,876330
....
並且該文件包含幾百行(每個OldValue都是唯一的)。我需要處理多個文件夾&子文件夾中的多個文本文件的更改。我最好猜測文件夾,文件和文本行數 - 15個文件夾,每個文件夾大約150個文本文件,每個文件夾中大約有65,000行文本(每個文本文件400-500行)。
我會在數據上做2遍,除非我可以在一個數據庫中完成。第一遍是生成一個文本文件,我將用它作爲檢查列表來檢查我的更改。第二遍是實際進行文件更改。另外,我只想更改字符串出現的文本文件(不是每個文件)。
我正在使用以下Powershell腳本來瀏覽文件&生成所需更改的列表。腳本運行,但速度非常慢。我還沒有在替代邏輯上工作,但我認爲它會類似於我所得到的。
# replace a string in a file with powershell
[reflection.assembly]::loadwithpartialname("Microsoft.VisualBasic") | Out-Null
Function Search {
# Parameters $Path and $SearchString
param ([Parameter(Mandatory=$true, ValueFromPipeline = $true)][string]$Path,
[Parameter(Mandatory=$true)][string]$SearchString
)
try {
#.NET FindInFiles Method to Look for file
[Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles(
$Path,
[Microsoft.VisualBasic.FileIO.SearchOption]::SearchAllSubDirectories,
$SearchString
)
} catch { $_ }
}
if (Test-Path "C:\Work\ListofAllFilenamesToSearch.txt") { # if file exists
Remove-Item "C:\Work\ListofAllFilenamesToSearch.txt"
}
if (Test-Path "C:\Work\FilesThatNeedToBeChanged.txt") { # if file exists
Remove-Item "C:\Work\FilesThatNeedToBeChanged.txt"
}
$filefolder1 = "C:\TestFolder\WorkFiles"
$ftype = "*.txt"
$filenames1 = Search $filefolder1 $ftype
$filenames1 | Out-File "C:\Work\ListofAllFilenamesToSearch.txt" -Width 2000
if (Test-Path "C:\Work\FilesThatNeedToBeChanged.txt") { # if file exists
Remove-Item "C:\Work\FilesThatNeedToBeChanged.txt"
}
(Get-Content "C:\Work\NumberXrefList.CSV" |where {$_.readcount -gt 1}) | foreach{
$OldFieldValue, $NewFieldValue = $_.Split("|")
$filenamelist = (Get-Content "C:\Work\ListofAllFilenamesToSearch.txt" -ReadCount 5) #|
foreach ($j in $filenamelist) {
#$testvar = (Get-Content $j)
#$testvar = (Get-Content $j -ReadCount 100)
$testvar = (Get-Content $j -Delimiter "\n")
Foreach ($i in $testvar)
{
if ($i -imatch $OldFieldValue) {
$j + "|" + $OldFieldValue + "|" + $NewFieldValue | Out-File "C:\Work\FilesThatNeedToBeChanged.txt" -Width 2000 -Append
}
}
}
}
$FileFolder = (Get-Content "C:\Work\FilesThatNeedToBeChanged.txt" -ReadCount 5)
Get-ChildItem $FileFolder -Recurse |
select -ExpandProperty fullname |
foreach {
if (Select-String -Path $_ -SimpleMatch $OldFieldValue -Debug -Quiet) {
(Get-Content $_) |
ForEach-Object {$_ -replace $OldFieldValue, $NewFieldValue }|
Set-Content $_ -WhatIf
}
}
在上面的代碼,我已經試過幾件事情與Get-Content
- default
,與-ReadCount
和-Delimiter
- 在試圖避免內存不足的錯誤。
我控制的唯一的東西是舊的&新替換字符串文件的長度。有沒有辦法在Powershell中做到這一點?有更好的選擇/解決方案嗎?我正在運行Windows 7,Powershell 3.0版。