【问题标题】:Powershell - Speeding up writing to filesPowershell - 加快写入文件的速度
【发布时间】:2015-04-19 16:59:19
【问题描述】:

我编写了这个脚本来查找目录中的所有文件夹,对于每个文件夹,检查一个公共文件中是否存在某些字符串,如果不存在则添加它们。我需要在特定的地方插入字符串。我真的不知道如何做到这一点,我选择了更简单的查找和替换需要插入字符串的位置。无论如何,这个脚本需要将近一个小时来处理 800 个文件。我希望一些有经验的成员可以指出使我的任务更快的方法,因为我只使用了 Powershell 两天。非常感谢!!!

# First find and replace items. 
$FindOne = 
$ReplaceOneA = 
$ReplaceOneB = 
$ReplaceOneC = 

# Second find and replace items. 
$FindTwo =
$ReplaceTwo =

# Strings to test if exist.
# To avoid duplicate entries.
$PatternOne = 
$PatternTwo = 
$PatternThree = 
$PatternFour = 

# Gets window folder names.
$FilePath = "$ProjectPath\$Station\WINDOW"
$Folders = Get-ChildItem $FilePath | Where-Object {$_.mode -match "d"}

# Adds folder names to an array.
$FolderName = @()
$Folders | ForEach-Object { $FolderName += $_.name }

# Adds code to each builder file.
ForEach ($Name in $FolderName) {

$File = "$FilePath\$Name\main.xaml"
$Test = Test-Path $File

# First tests if file exists. If not, no action.
If ($Test -eq $True) {

$StringOne = Select-String  -pattern $PatternOne -path $File 
$StringTwo = Select-String  -pattern $PatternTwo -path $File 
$StringThree = Select-String  -pattern $PatternThree -path $File 
$StringFour = Select-String  -pattern $PatternFour -path $File

$Content = Get-Content $File

# If namespaces or object don't exist, add them.
If ($StringOne -eq $null) {

$Content = $Content -Replace $FindOne, $ReplaceOneA
}

If ($StringTwo -eq $null) {

$Content = $Content -Replace $FindOne, $ReplaceOneB
}

If ($StringThree -eq $null) {

$Content = $Content -Replace $FindOne, $ReplaceOneC
}

If ($StringFour -eq $null) {

$Content = $Content -Replace $FindTwo, $ReplaceTwo
}

$Content | Set-Content $File

}

}

# End of program.

【问题讨论】:

  • 给定 800 个文件,您实际上执行了多达 3200 次查找/替换运行,因为您在循环中处理每个文件 FOUR 次...
  • 感谢您的回复。有什么想法可以让它更简单但达到相同的结果?
  • 加载文件一次,然后你的 foreach/set-content 运行吗?不过,从未真正使用过 powershell,所以不知道是否每次都必须获取内容才能加载新修改的版本。
  • 你是对的。无需多次获取内容。我会看看它加速了多少。如果其他成员看到最佳实践的进一步改进,请加入...谢谢 Marc!
  • @MarcB 有正确的方法。只需确保每次执行替换时都设置了$content 的内容,即$content = $content -replace $FindOne, $ReplaceOne。一旦你完成了每个你可以做$content | Set-Content $File

标签: performance powershell replace find


【解决方案1】:

您可以尝试使用流写入文件,如下所示

$stream = [System.IO.StreamWriter] $File
$stream.WriteLine($content)
$stream.close()

【讨论】:

  • 嗨,我没有遇到过这种方法。我按照你写的那样写,但是它用字符串填充了每个文件,没有别的“System.Object[]”?
  • 嗨,我使用了“$Content”,它的输出很好。但是,保持文本格式很重要。我认为streamwriter不可能做到这一点,我猜它的重点是,你不在乎吗?干杯!
  • 如果你需要,你仍然可以逐行写出来,我的例子只是一个简单的例子来说明这个想法。
  • 你能指出我正确的方向吗?我需要创建一个包含我的每一行内容的数组然后写出来吗?再次感谢!
猜你喜欢
  • 2011-06-25
  • 2020-02-06
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多