我正在尝试覆盖用Write-Host编写的PowerShell中的一行(我有一个循环运行的进程,我想在屏幕上显示更新百分比).我试图做的是:
Write-Host -NoNewline "`rWriting $outputFileName ($i/$fileCount)... $perc%"
Run Code Online (Sandbox Code Playgroud)
但它不是覆盖线,而是保持在同一条线上并附加到它上面.
我在这里想念的是什么?
谢谢
Raf*_*Raf 20
您无法在Powershell窗口中覆盖一行.你可以做的是用cls
(Clear-Host)空白窗口:
# loop code
cls
Write-Host "`rWriting $outputFileName ($i/$fileCount)... $perc%"
# end loop
Run Code Online (Sandbox Code Playgroud)
但是你真正应该使用的是Write-Progress
一个专门为此目的而构建的cmdlet:
# loop code
Write-Progress -Activity "Writing $outputFileName" -PercentComplete $perc
# end loop
Run Code Online (Sandbox Code Playgroud)
更多信息,请Write-Progress
访问:http://technet.microsoft.com/en-us/library/hh849902.aspx
Dul*_*son 14
作为对Raf上述答案的调整,您不必每次都擦除屏幕以更新最后一行.调用Write-Host
与-NoNewLine
并回车`r
就足够了.
for ($a=0; $a -le 100; $a++) {
Write-Host -NoNewLine "`r$a% complete"
Start-Sleep -Milliseconds 10
}
Write-Host #ends the line after loop
Run Code Online (Sandbox Code Playgroud)
Mat*_*att 10
它并不完美,但这里有一个旋转角色的脚本.允许您这样做的部分是:
$origpos = $host.UI.RawUI.CursorPosition
$origpos.Y += 1
Run Code Online (Sandbox Code Playgroud)
获取当前位置并保存,以便我们可以继续参考它.随着你的进步,你改变了$host.UI.RawUI.CursorPosition
.由于之前保存过,您可以重置它$host.UI.RawUI.CursorPosition = $origpos
.你应该能够尝试一下.
$scroll = "/-\|/-\|"
$idx = 0
$job = Invoke-Command -ComputerName $env:ComputerName -ScriptBlock { Start-Sleep -Seconds 10 } -AsJob
$origpos = $host.UI.RawUI.CursorPosition
$origpos.Y += 1
while (($job.State -eq "Running") -and ($job.State -ne "NotStarted"))
{
$host.UI.RawUI.CursorPosition = $origpos
Write-Host $scroll[$idx] -NoNewline
$idx++
if ($idx -ge $scroll.Length)
{
$idx = 0
}
Start-Sleep -Milliseconds 100
}
# It's over - clear the activity indicator.
$host.UI.RawUI.CursorPosition = $origpos
Write-Host 'Complete'
Remove-Variable('job')
$job = Start-Job -ScriptBlock { Start-Sleep -Seconds 10 }
while (($job.State -eq "Running") -and ($job.State -ne "NotStarted"))
{
Write-Host '.' -NoNewline
Start-Sleep -Seconds 1
}
Write-Host ""
Run Code Online (Sandbox Code Playgroud)
因此,记录您想要返回的日志,然后您可以使用此逻辑.这在ISE中无法正常工作.您也可以使用`b作为后退空格字符.
您可以使用.NET控制台类在您想要的位置执行您想要的操作.仅适用于控制台窗口,而不适用于ISE.
cls
[Console]::SetCursorPosition(40,5)
[Console]::Write('Value of $i = ')
[Console]::SetCursorPosition(40,7)
[Console]::Write('Value of $j = ')
For ($i = 1; $i -lt 11; $i++)
{
[Console]::SetCursorPosition(57,5)
[Console]::Write($i)
for ($j = 1; $j -lt 11; $j++)
{
[Console]::SetCursorPosition(57,7)
[Console]::Write("$j ")
Start-Sleep -Milliseconds 200
}
Start-Sleep -Milliseconds 200
}
[Console]::SetCursorPosition(40,5)
[Console]::Write(" `n")
[Console]::SetCursorPosition(40,7)
[Console]::Write(" `n")
[Console]::SetCursorPosition(0,0)
Run Code Online (Sandbox Code Playgroud)
如果目标是严格覆盖Powershell控制台提示符行(带有光标的当前行),则此处的所有答案仅在一定程度上起作用,并且在某些方面做了超出期望的事情。
像Dullson指出的那样,在第一行中使用Clear-Host cmdlet(cls)的Raf和Craig的答案做得太多。消隐整个屏幕时,假定清除的内容对于查看不再重要,这可能并非如此。有时这些对于理解当前行是必要的。
Raf的Write-Progress解决方案是一个功能强大的cmdlet,但似乎仅覆盖当前行就显得过大了。
Raf的Write-Host建议,Matt的提交和Dullson的调整都很好,因为在确定的屏幕位置仅一个字符位置需要更新,或者后续行文本的长度比当前更长。如果不是这样,则后继行文本将仅覆盖当前行的长度,而使后继行中长度位置比新行长的部分与新行一起保留在视图中。
例如,如果先前的值为10,而新的值为9,则显示的值为90。数字9只会覆盖先前值的等于其长度-1的部分。因此,解决方案对增量有效,但不适用于对于值的长度与以前相比减少的递减效果非常好。
以下块显示了如何确保用新的行文本完全(可视)覆盖。
$LongString = "This string is long"
$ShortString = "This is short"
#Simulate typing a string on the console line
$L = 1
While ($L -le $LongString.Length)
{
$Sub = $LongString.Substring(0,$L)
Write-Host "`r$Sub" -NoNewline
$L++
# This sleep is just to simulate manual typing delay
Start-Sleep -Milliseconds 20
}
# Now blank out the entire line with the space character " "
# The quantity of spaces should be equal to the length of the current text
# Which in this case is contained in $Sub.Length
$Blank = " "
For($L = 1; $L -le $Sub.Length; $L++)
{
$Blank = $Blank + " "
}
Write-Host "`r$Blank" -NoNewline
# Overwrite the blank console line with the new string
$L = 1
While ($L -le $ShortString.Length)
{
$Sub = $ShortString.Substring(0,$L)
Write-Host "`r$Sub" -NoNewline
$L++
# This sleep is just to simulate delay in manual typing
Start-Sleep -Milliseconds 20
}
# The following is not required if you want the Powershell prompt
# to resume to the next line and not overwrite current console line.
# It is only required if you want the Powershell prompt to return
# to the current console line.
# You therefore blank out the entire line with spaces again.
# Otherwise prompt text might be written into just the left part of the last
# console line text instead of over its entirety.
For($L = 1; $L -le $Sub.Length; $L++)
{
$Blank = $Blank + " "
}
Write-Host "`r$Blank" -NoNewline
Write-Host "`r" -NoNewline
Run Code Online (Sandbox Code Playgroud)
小智 5
我知道,那已经很老了,但我处于同样的情况并修改了 Boluwade Kujero 的解决方案,只是因为在写入新输出之前写入空行可能会导致“闪烁”输出。
所以在下面的函数中,我只是覆盖现有的行,写空格直到到达旧的光标位置,然后回到新行的最后一个字符。
此外,我添加了一个光学进度条。该函数通过给定的参数计算进度:
function Write-Status
{
param([int]$Current,
[int]$Total,
[string]$Statustext,
[string]$CurStatusText,
[int]$ProgressbarLength = 35)
# Save current Cursorposition for later
[int]$XOrg = $host.UI.RawUI.CursorPosition.X
# Create Progressbar
[string]$progressbar = ""
for ($i = 0 ; $i -lt $([System.Math]::Round($(([System.Math]::Round(($($Current) / $Total) * 100, 2) * $ProgressbarLength) / 100), 0)); $i++) {
$progressbar = $progressbar + $([char]9608)
}
for ($i = 0 ; $i -lt ($ProgressbarLength - $([System.Math]::Round($(([System.Math]::Round(($($Current) / $Total) * 100, 2) * $ProgressbarLength) / 100), 0))); $i++) {
$progressbar = $progressbar + $([char]9617)
}
# Overwrite Current Line with the current Status
Write-Host -NoNewline "`r$Statustext $progressbar [$($Current.ToString("#,###").PadLeft($Total.ToString("#,###").Length)) / $($Total.ToString("#,###"))] ($($( ($Current / $Total) * 100).ToString("##0.00").PadLeft(6)) %) $CurStatusText"
# There might be old Text behing the current Currsor, so let's write some blanks to the Position of $XOrg
[int]$XNow = $host.UI.RawUI.CursorPosition.X
for ([int]$i = $XNow; $i -lt $XOrg; $i++) {
Write-Host -NoNewline " "
}
# Just for optical reasons: Go back to the last Position of current Line
for ([int]$i = $XNow; $i -lt $XOrg; $i++) {
Write-Host -NoNewline "`b"
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用函数:
For ([int]$i=0; $i -le 8192; $i++) {
Write-Status -Current $i -Total 8192 -Statustext "Running a long Task" -CurStatusText "Working on Position $i"
}
Run Code Online (Sandbox Code Playgroud)
结果将是一个正在运行的进度条,如下所示(在一行中):
运行一个长任务??????????????????????????????????????? [4.242 / 8.192] ( 51,78 %) 在位置 4242 工作
希望这会帮助别人
归档时间: |
|
查看次数: |
34482 次 |
最近记录: |