PowerShell - Write-Host로 쓴 줄 덮어쓰기
PowerShell에서 Write-Host로 작성된 줄을 덮어쓰려고 합니다(루프에서 실행 중인 프로세스가 있고 화면에 업데이트된 비율을 표시하려고 합니다).제가 시도한 것은 다음과 같습니다.
Write-Host -NoNewline "`rWriting $outputFileName ($i/$fileCount)... $perc%"
그러나 선을 덮어쓰는 대신 동일한 선에 유지되고 추가됩니다.
여기서 내가 놓친 게 뭐죠?
감사해요.
Powershell 창에서 선을 덮어쓸 수 없습니다.당신이 할 수 있는 것은 창문을 비우는 것입니다.cls
호스트 이름):
# loop code
cls
Write-Host "`rWriting $outputFileName ($i/$fileCount)... $perc%"
# end loop
하지만 당신이 정말로 사용해야 하는 것은Write-Progress
목적을 제작된 : 이 목 적 제 작 된 히 별 cmdlet:
# loop code
Write-Progress -Activity "Writing $outputFileName" -PercentComplete $perc
# end loop
더 많은 정보Write-Progress
여기: http://technet.microsoft.com/en-us/library/hh849902.aspx
위의 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
완벽하지는 않지만 회전하는 캐릭터가 있는 대본이 있습니다.이 작업을 수행할 수 있는 부분은 다음과 같습니다.
$origpos = $host.UI.RawUI.CursorPosition
$origpos.Y += 1
현재 위치를 가져와서 저장하면 계속 참조할 수 있습니다.진행함에 따라 다음 사항을 변경할 수 있습니다.$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 ""
그래서 여러분이 어디로 돌아가고 싶은지 기억하는 한 이 논리를 사용할 수 있습니다.이것은 ISE에서 제대로 작동하지 않습니다.b를 백스페이스 문자로 사용할 수도 있습니다.
저는 그것이 꽤 오래되었다는 것을 알고 있습니다. 하지만 저는 새로운 출력을 쓰기 전에 빈 줄을 쓰는 것이 "깜빡이는" 출력을 초래할 수 있다는 이유로 볼루와데 쿠제로의 솔루션을 수정하지 않고 같은 상황에 있었습니다.
따라서 다음 기능에서는 기존 행을 덮어쓰고 이전 커서 위치에 도달할 때까지 공백을 쓴 다음 새 행의 마지막 문자로 돌아갑니다.
추가로 광학 진행 표시줄을 추가했습니다.진행률은 주어진 파라미터를 통해 함수에 의해 계산됩니다.
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"
}
}
다음과 같은 기능을 사용합니다.
For ([int]$i=0; $i -le 8192; $i++) {
Write-Status -Current $i -Total 8192 -Statustext "Running a long Task" -CurStatusText "Working on Position $i"
}
결과적으로 다음과 같은 진행률 표시줄이 실행됩니다(한 줄로).
긴 작업 실행 ████████████████░░░░░░░░░░ [4.242 / 8.192] (51,78%) Position 4242에서 작업
이것이 다른 사람에게 도움이 되기를 바랍니다.
를 사용할 수 있습니다.원하는 위치에서 원하는 작업을 정확히 수행할 수 있는 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)
PowerShell 콘솔 프롬프트 줄(커서가 있는 현재 줄)을 완전히 덮어쓰는 것이 목표인 경우 여기에 있는 모든 응답은 어느 정도까지만 작동하며 어떤 면에서는 원하는 이상의 작업을 수행합니다.
Dulson이 언급한 것처럼 첫 번째 줄에 Clear-Host cmdlet(cls)을 사용하는 Raf와 Craig의 답변은 너무 많은 것을 하고 있습니다.전체 화면을 비우면 지워진 항목이 더 이상 사실이 아닐 수도 있는 항목을 보는 데 중요하지 않다고 가정합니다.때때로 이것들은 현재 라인을 이해하기 위해 필요합니다.
Raf의 Write-Progress 솔루션은 강력한 cmdlet이지만 현재 줄을 덮어쓰는 것만으로도 오버킬처럼 보입니다.
라프의 쓰기 호스트 제안, 매트의 제출, 덜슨의 트위크는 모두 확실한 화면 위치에서 하나의 캐릭터 위치만 업데이트해야 하거나 후속 라인 텍스트의 길이가 현재보다 긴 경우에 좋습니다.그렇지 않은 경우, 후속 라인 텍스트는 길이가 새 라인보다 긴 후속 라인의 부분만 새 라인과 함께 표시되도록 하여 현재 라인을 덮어씁니다.
예를 들어, 이전 값이 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
이것은 Thomas Rayner의 블로그 게시물에서 얻은 것입니다. 위치를 저장합니다.[s
커서 위치를 합니다.[u
$E=[char]27
그런 다음 이스케이프 저장 시퀀스를 사용하여 현재 커서 위치를 저장합니다.
"${E}[s"
: 사용하기: 업데이트 순서 사용하기${E}[u
PS에 문자열을 시작할 위치를 알려주는 방법:
1..10 | %{"${E}[uThere are $_ s remaining"; Start-Sleep -Seconds 1}
그러나 ISE에서는 작동하지 않습니다.
링크가 오래된 것은 알지만 오늘은 여기에 있습니다.
해라
for ($i=1;$i -le 100;$i++){Write-Host -NoNewline "`r" $i;sleep 1}
https://241931348f64b1d1.wordpress.com/2017/08/23/how-to-write-on-the-same-line-with-write-output/
이 방법은 상태가 "Successed"로 변경될 때까지 루프에 출력 값을 기록하는 데 사용되었습니다.필요한 줄 수만큼 커서를 설정하고 동일한 줄을 덮어씁니다.
while($val -ne 1)
{
if($taskstates.Tasks.state[0] -eq "Succeeded" -and $taskstates.Tasks.state[1] -eq "Succeeded" -and $taskstates.Tasks.state[2] -eq "Succeeded" -and $taskstates.Tasks.state[3] -eq "Succeeded")
{
$val = 1
}
#Clear-Host
$taskstates.Tasks.StartTime[0].ToString() +" "+ $taskstates.Tasks.name[0] +" is "+ $taskstates.Tasks.state[0]
$taskstates.Tasks.StartTime[1].ToString() +" "+ $taskstates.Tasks.name[1] +" is "+ $taskstates.Tasks.state[1]
$taskstates.Tasks.StartTime[2].ToString() +" "+ $taskstates.Tasks.name[2] +" is "+ $taskstates.Tasks.state[2]
$taskstates.Tasks.StartTime[3].ToString() +" "+ $taskstates.Tasks.name[3] +" is "+ $taskstates.Tasks.state[3]
$taskstates = Get-ASRJob -Name $failoverjob.Name
"ASR VMs build is in Progress"
Start-Sleep 5
[console]::setcursorposition($([console]::Cursorleft ),$([console]::CursorTop - 4))
}
파티에 늦었어요.여기 제가 최근에 발견하고 제 목적에 맞게 수정한 개념 증명이 있습니다.이 예는 선을 덮어씁니다.
$count = 1
# Used for calculating the max number length for padding trailing spaces
$totalCount = 100
#Get current cursor position
$curCursorPos = New-Object System.Management.Automation.Host.Coordinates
$curCursorPos.X = $host.ui.rawui.CursorPosition.X
$curCursorPos.Y = $host.ui.rawui.CursorPosition.Y
# Counter code
While ($count -le 100) {
# Keep cursor in the same position on the same line
$host.ui.rawui.CursorPosition = $curCursorPos
# Display with padded trailing spaces to overwrite any extra digits
$pad = ($totalCount -as [string]).Length
# Display the counter
Write-Host "$(([string]$count).Padright($pad))" -NoNewline -ForegroundColor Green
# Run through the example quickly
Start-Sleep -Milliseconds 100
#increment $count
$count++
}
당신은 실험할 수 있습니다.Write-Host -NoNewline
자산을 유지하거나 제거함으로써 어떤 것이 더 잘 어울리는지 확인할 수 있습니다.
나는 아래 코드가 좋습니다...
$dots = ""
while (!$isTrue) {
if ($dots -eq "...") {
$dots = ""
}
else {
$dots += "."
}
Write-Host -NoNewLine "`rLoading$dots"
Start-Sleep 1
}
$Host를 사용할 수 있습니다.UI.원시 UI.창 크기.표시 너비를 찾은 다음 사용할 너비입니다.PadRight: 줄을 공백으로 채웁니다.이것은 각 루프에서 화면을 지울 필요, 마지막 루프에서 지속된 문자 문제, 커서 위치를 조작해야 하는 문제, 사용자 지정 함수 또는 많은 번거로운 코드를 작성해야 하는 문제 등을 방지합니다.
# only works in a console window
If ($Host.Name -eq "ConsoleHost")
{
Write-Host 'Starting...'
# find the max line length of the console host
$maxLineLength = $Host.UI.RawUI.WindowSize.Width
# loop a few times
For ($i = 1; $i -le 10; $i++)
{
# for the sake of demonstration, generate a random-length string of letters
$randStringLength = Get-Random -Minimum 1 -Maximum $maxLineLength
$randCharIndex = Get-Random -Minimum 65 -Maximum (65+26) # A = ASCII 65
$randChar = ([char]$randCharIndex)
$myString = [string]$randChar*$randStringLength
# overwrite at the current console line
Write-Host ("`r"+$myString.PadRight($maxLineLength," ")) -NoNewline
# pause briefly before going again
Start-Sleep -Milliseconds 200
}
Write-Host 'Done.'
}
PowerShell 7.2+의 다른 옵션은 최소 쓰기 진행률 보기를 사용하는 것입니다.
# only works in a console window
If ($Host.Name -eq "ConsoleHost")
{
# loop a few times
For ($i = 1; $i -le 10; $i++)
{
# for the sake of demonstration, generate a random-length string of letters
$randStringLength = Get-Random -Minimum 1 -Maximum 500
$randCharIndex = Get-Random -Minimum 65 -Maximum (65+26) # A = ASCII 65
$randChar = ([char]$randCharIndex)
$myString = [string]$randChar*$randStringLength
# overwrite at the current console line
Write-Progress -Activity $i -Status $myString
# pause briefly before going again
Start-Sleep -Milliseconds 200
}
}
여기 좋은 제안들이 많이 있습니다...
WindowTitle 막대를 사용하여 스크립트의 상태를 모니터링하고 코드 내 위치 및 현재 진행 상황을 표시합니다.
($t = 0, $t -le 100, $t++)에 대해 {
$Host.UI.RawUI.WindowTitle = "진행률 - $t% 완료"
시동-슬립 - 밀리초 10
}
코드 내에 업데이트된 "위치" 정보를 삽입하여 코드 내의 위치를 표시합니다.
$Host.UI.RawUI.WindowTitle = "인덱스 쿼리 중...."
$Host.UI.RawUI.WindowTitle = "검색 필드를 업데이트하는 중...."
$Host.UI.RawUI.WindowTitle = "Robocopy 수행 중...."
그리고 물론 그것이 완성되면:
$Host.UI.RawUI.WindowTitle = "스크립트가 완료되었습니다."
언급URL : https://stackoverflow.com/questions/25846889/powershell-overwriting-line-written-with-write-host
'it-source' 카테고리의 다른 글
도커 컨테이너를 중지 및 제거하는 단일 명령 (0) | 2023.08.14 |
---|---|
최소한의 메모리 사용으로 PHP에서 어레이와 같은 구조가 필요합니다. (0) | 2023.08.09 |
Symfony2 엔티티 모음 - 기존 엔티티와의 연결을 추가/제거하는 방법은 무엇입니까? (0) | 2023.08.09 |
Git Bash로 사용자 및 암호 구성 (0) | 2023.08.09 |
파이썬으로 화면을 지우는 방법 (0) | 2023.08.09 |