PowerShell 脚本速度独立与 Visual Code 内
Posted
技术标签:
【中文标题】PowerShell 脚本速度独立与 Visual Code 内【英文标题】:PowerShell script speed standalone vs within Visual Code 【发布时间】:2021-09-06 15:02:09 【问题描述】:我有一个简单的 PowerShell 脚本,可以将最近添加的文件列表写入文件。
$fpath = "\\DS1821\video\movies"
$file1 = "C:\Users\brian.w.williams\Desktop\RecentMovie.txt"
if (Test-Path $file1) Remove-Item -Path $file1
Get-ChildItem -Path "$fpath" -File -Recurse -Include "*.eng.srt" |
ForEach-Object
$movie = $_.BaseName -replace ".eng",""
if ( ($_.LastWriteTime.Month -ge 7) -and ($_.LastWriteTime.Year -ge 2021) )
Write-Host $movie " = " $_.LastWriteTime
Write-Output $movie | Out-file $file1 -append;
脚本运行良好。但是我注意到在可视代码中运行时脚本运行得更快(几分钟)(即“运行而不调试”)。当我独立运行脚本(即“使用 PowerShell 运行”)时,脚本可能需要数小时才能完成。为什么有区别?我有什么办法可以加快速度吗?我已经尝试映射网络文件夹,但没有任何区别。
【问题讨论】:
听起来您正在体验 Windows PowerShell 5.1(Windows 附带的版本)和 PowerShell 7(VScode 的 PowerShell 扩展附带的版本)之间的差异。 虽然与速度性能无关,但最好为文件创建一个独立于平台的路径。$File1 = Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop' -AdditionalChildPath 'RecentMovie.txt'
我们还没有收到您的来信.. 作为 SO 新手您可能不知道这一点,但习惯上点击左侧的 ✓ 图标 accept the answer that best solved your problem .这将帮助其他有类似问题的人更轻松地找到它,并有助于激发人们回答您的问题。
【参考方案1】:
有待改进以帮助代码加速。
首先,在 ForEach 循环中使用Write-Host
和Write-Output
追加到文件是非常耗时的。
然后您在 Get-ChildItem 上使用参数 -Include
,而您确实想在其中使用 -Filter
。 Filter 比 Include 快得多,因为后者只会在之后过滤文件名。 -Filter
但是只能在一个文件名模式上工作,但这正是您在这里所做的。
if(..)
也可以改进为仅比较一个值(日期时间),而不是 LastWriteTime 中的两个单独属性。
试试:
$sourcePath = '\\DS1821\video\movies'
# set a variable to an output file on your desktop
$outputFile = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath 'RecentMovies.txt'
# set the reference date in a variable for faster comparison later
$refdate = (Get-Date -Year 2021 -Month 7 -Day 1).Date
# get the files, filter on the name ending in '*.eng.srt'
# filter more with Where-Object so you'll get only files newer than or equal to the reference date
# output objects with one calculated property ('MovieName') and the LastWriteTime
$movies = Get-ChildItem -Path $sourcePath -File -Recurse -Filter '*.eng.srt' |
Where-Object $_.LastWriteTime -ge $refdate |
Select-Object @Name = 'MovieName'; Expression = $_.BaseName -replace '\.eng\.srt$', '.srt',
LastWriteTime
# now output what you have collected to file.
# Set-Content creates a new file or overwrites an existing file
$movies.MovieName | Set-Content -Path $outputFile
# and to screen
$movies | ForEach-Object Write-Host ('0 = 1' -f $_.MovieName, $_.LastWriteTime.ToString())
# or to Out-GridView if you prefer
$movies | Out-GridView -Title 'My Movies'
1.我更改了一些变量名称以使代码更易读
2. 由于-replace
使用正则表达式,您必须用反斜杠转义点。正则表达式还将字符串锚定到 BaseName 的末尾,末尾带有美元符号 ($
)
【讨论】:
以上是关于PowerShell 脚本速度独立与 Visual Code 内的主要内容,如果未能解决你的问题,请参考以下文章
powershell 各种CMD Batch,Powershell和Visual Basic脚本文件
无法在 Visual Studio Code 中调试 PowerShell 脚本
从PowerShell设置Visual Studio环境变量
Azure Service Fabric 从 Visual Studio 发布升级 - PowerShell 脚本错误