【发布时间】:2014-03-14 16:58:41
【问题描述】:
我有一个目录,其中包含约 3000 个文本文件,当我将程序转换到新服务器时,我会定期搜索和替换这些文本文件。
每个文本文件可能平均有约 3000 行,我需要一次搜索文件以查找 300 到 1000 个术语。
我正在替换与我正在搜索的字符串相关的服务器前缀。因此,对于每一个 csv 条目,我都在寻找 Search_String、\\Old_Server\"Search_String" 并确保在程序完成后,结果是 "\\New_Server\Search_String"。
我拼凑了一个 powershell 程序,它可以工作。但它太慢了,我从未见过它完整。
有什么让它更快的建议吗?
编辑 1: 我按照建议更改了 get-content,但仍然需要 3 分钟来搜索两个文件(约 8000 行)以获取 9 个单独的搜索词。我一定还在搞砸;如果手动完成 9 次,notepad++ 搜索和替换仍然会更快。
我不确定如何删除第一个 (Get-Content),因为我想在对文件进行任何更改之前制作文件的副本以进行备份。
编辑 2: 所以这要快一个数量级;它可能在 10 秒内搜索文件。但是现在它不会将更改写入文件,它只会搜索目录中的第一个文件!我没有更改该代码,所以我不知道它为什么会损坏。
编辑 3: 成功!我调整了下面发布的解决方案,使其更快。它现在在几秒钟内搜索每个文件。我可能会颠倒循环顺序,以便它将文件加载到数组中,然后搜索并替换 CSV 中的每个条目,而不是相反。如果我让它工作,我会发布它。
最终脚本如下供参考。
#get input from the user
$old = Read-Host 'Enter the old cimplicity qualifier (F24, IRF3 etc'
$new = Read-Host 'Enter the new cimplicity qualifier (CB3, F24_2 etc)'
$DirName = Get-Date -format "yyyy_MM_dd_hh_mm"
New-Item -ItemType directory -Path $DirName -force
New-Item "$DirName\log.txt" -ItemType file -force -Value "`nMatched CTX files on $dirname`n"
$logfile = "$DirName\log.txt"
$VerbosePreference = "SilentlyContinue"
$points = import-csv SearchAndReplace.csv -header find #Import CSV File
#$ctxfiles = Get-ChildItem . -include *.ctx | select -expand fullname #Import local directory of CTX Files
$points | foreach-object { #For each row of points in the CSV file
$findvar = $_.find #Store column 1 as string to search for
$OldQualifiedPoint = "\\\\"+$old+"\\" + $findvar #Use escape slashes to escape each invidual bs so it's not read as regex
$NewQualifiedPoint = "\\"+$new+"\" + $findvar #escape slashes are NOT required on the new string
$DuplicateNew = "\\\\" + $new + "\\" + "\\\\" + $new + "\\"
$QualifiedNew = "\\" + $new + "\"
dir . *.ctx | #Grab all CTX Files
select -expand fullname | #grab all of those file names and...
foreach {#iterate through each file
$DateTime = Get-Date -Format "hh:mm:ss"
$FileName = $_
Write-Host "$DateTime - $FindVar - Checking $FileName"
$FileCopied = 0
#Check file contents, and copy matching files to newly created directory
If (Select-String -Path $_ -Pattern $findvar -Quiet ) {
If (!($FileCopied)) {
Copy $FileName -Destination $DirName
$FileCopied = 1
Add-Content $logfile "`n$DateTime - Found $Findvar in $filename"
Write-Host "$DateTime - Found $Findvar in $filename"
}
$FileContent = Get-Content $Filename -ReadCount 0
$FileContent =
$FileContent -replace $OldQualifiedPoint,$NewQualifiedPoint -replace $findvar,$NewQualifiedPoint -replace $DuplicateNew,$QualifiedNew
$FileContent | Set-Content $FileName
}
}
$File.Dispose()
}
【问题讨论】:
-
您仍然在条件检查中使用 get-content,所以仍然需要很长时间。只需进行替换然后检查您是否更改了任何内容并将其输出为您的“XX found”会更快
标签: search powershell csv optimization text