gpt4 book ai didi

powershell - 如何在流水线函数中使用 Write-Progress?

转载 作者:行者123 更新时间:2023-12-04 17:50:31 37 4
gpt4 key购买 nike

我正在尝试在 PowerShell 中编写一个函数接受管道输入。我想使用 Write-Progress 显示进度条,管道中每个项目的增量。

例如:

function Write-PipelineProgress {
[Cmdletbinding()]
Param
(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] `
[object[]] $Input,

[string] $Activity = "Processing items"
)

Begin { Write-Progress -Activity $Activity -Status "Preparing" }

Process {
# how do i determine how much progress we've made?
$percentComplete = ... ?
Write-Progress -Activity $Activity -Status "Working" -PercentComplete $percentComplete

# return current item, so processing can continue
$_
}

End { Write-Progress -Activity $Activity -Status "End" -Completed }
}

Get-ChildItem | Write-PipelineProgress -Activity "Listing files"

我如何确定进度(完成百分比)?

最佳答案

您需要知道管道中的项目数量才能跟踪进度。

Powershell 3.0 可以让您对管道中的内容进行计数,而除了访问 .Count 之外,您无需做任何其他工作。 $Input 的属性(property)如果正确声明了管道参数。这也意味着您可以取消 begin {} process {} end {}块,如果需要,只需有一个简单的功能。

早期版本没有 Count属性,因此您首先必须遍历并捕获管道以获取计数,然后再次处理,这不是那么有效,我将在后面展示。

Powershell V2 版本:

function Show-ProgressV2{
param (
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
[PSObject[]]$InputObject,
[string]$Activity = "Processing items"
)

Begin {$PipeArray = @()}

Process {$PipeArray+=$InputObject}

End {
[int]$TotItems = ($PipeArray).Count
[int]$Count = 0

$PipeArray|foreach {
$_
$Count++
[int]$percentComplete = [int](($Count/$TotItems* 100))
Write-Progress -Activity "$Activity" -PercentComplete "$percentComplete" -Status ("Working - " + $percentComplete + "%")
}
}
}

Powershell V3 版本:
function Show-ProgressV3{
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
[PSObject[]]$InputObject,
[string]$Activity = "Processing items"
)

[int]$TotItems = $Input.Count
[int]$Count = 0

$Input|foreach {
$_
$Count++
[int]$percentComplete = ($Count/$TotItems* 100)
Write-Progress -Activity $Activity -PercentComplete $percentComplete -Status ("Working - " + $percentComplete + "%")
}
}

效率
比较两者,V3 函数大约快 5-6 倍,具体取决于管道的大小。

考虑以下预先过滤的文件列表,查找所有 .jpg我的主驱动器中的文件,根据您的评论,选择前 200 个文件并排序和列出,在管道中使用该功能 3 次:
$V2 = Measure-Command {Get-ChildItem -Filter *.jpg -Recurse `
| Show-ProgressV2 -Activity "Selecting" `
| Select-Object -First 200 `
| Show-ProgressV2 -Activity "Sorting" `
| Sort-Object -Property FullName `
| Show-ProgressV2 -Activity "Listing" `
| FL}

$V3 = Measure-Command {Get-ChildItem -filter *.jpg -Recurse `
| Show-ProgressV3 -Activity "Selecting" `
| Select-Object -First 200 `
| Show-ProgressV3 -Activity "Sorting" `
| Sort-Object -Property FullName `
| Show-ProgressV3 -Activity "Listing" `
| FL}

$V2
$V3

这给了我以下时间:
PS C:\Users\Graham> C:\Users\Graham\Documents\Stack_ShowProgress_Pipeline.ps1


Days : 0
Hours : 0
Minutes : 0
Seconds : 48
Milliseconds : 360
Ticks : 483607111
TotalDays : 0.000559730452546296
TotalHours : 0.0134335308611111
TotalMinutes : 0.806011851666667
TotalSeconds : 48.3607111
TotalMilliseconds : 48360.7111

Days : 0
Hours : 0
Minutes : 0
Seconds : 8
Milliseconds : 335
Ticks : 83358374
TotalDays : 9.6479599537037E-05
TotalHours : 0.00231551038888889
TotalMinutes : 0.138930623333333
TotalSeconds : 8.3358374
TotalMilliseconds : 8335.8374

关于powershell - 如何在流水线函数中使用 Write-Progress?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17605364/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com