将PowerShell输出字符串覆盖到同一行

问题描述 投票:4回答:2

我有一段PS代码,它采用7-Zip提取输出并将其过滤掉,因此只有百分比“%”进度更新行被打印。我已设法将其降低到只有百分比输出:

& $7ZipPath "x" $filePath "-o$extractionPath" "-aos" "-bsp1" | out-string -stream | Select-String -Pattern "\d{1,3}%" -AllMatches | ForEach-Object { $_.Matches.Value } | Write-Host -NoNewLine

目前控制台输出如下所示:

0%1%5%9%14%17%20%23%26%31%37%43%46%48%50%52%54%56%59%61%63%65%67%70%72%74%76%78%80%81%82%83%85%86%87%89%90%91%92%94%95%96%97%98%99%

有没有办法将这些输出保持在相同的位置,在同一条线上,使它们只是相互覆盖?这很棘手,因为输出来自7-Zip应用程序。我担心我不能使用Expand-Archive,因为我正在处理.7z文件

非常感谢!

powershell pipe 7zip
2个回答
4
投票

你可以使用.Net System.Console类:

[System.Console]::SetCursorPosition(0, [System.Console]::CursorTop)

所以你的代码必须是:

& $7ZipPath "x" $filePath "-o$extractionPath" "-aos" "-bsp1" | out-string -stream | Select-String -Pattern "\d{1,3}%" -AllMatches | ForEach-Object { $_.Matches.Value } | foreach {
    [System.Console]::SetCursorPosition(0, [System.Console]::CursorTop) 
    Write-Host $_ -NoNewLine
}

注意:只要下一个输出的长度相等或更长,在您的情况下就是如此,这就是您所需要的。否则你必须先清除最后一个输出。


1
投票

marsze's helpful answer运行良好,但有一个更简单的替代方法,使用CR字符("`r")将光标位置重置为行的开头。

这是一个简单的演示,在同一行打印数字1到10:

1..10 | ForEach-Object { Write-Host -NoNewline "`r$_"; Start-Sleep -Milliseconds 100 }

[Console]::Write(...)指出,Write-Host -NoNewline ...而不是Bacon Bits也有效。

但是,相同的约束适用:如果先前的输出行恰好更长,则额外的字符会延续。

要解决此问题,您必须将任何输出行填充到控制台窗口缓冲区宽度的长度:

'loooooooong', 'meeedium', 'short' | ForEach-Object { 
   Write-Host -NoNewline ("`r{0,-$([console]::BufferWidth)}" -f $_)
   Start-Sleep -Milliseconds 500 
}
© www.soinside.com 2019 - 2024. All rights reserved.