如何在PowerShell中输出没有换行符的文本?

我想我的PowerShell脚本打印这样的东西:

Enabling feature XYZ......Done 

脚本看起来像这样:

 Write-Output "Enabling feature XYZ......." Enable-SPFeature... Write-Output "Done" 

但是Write-Output总是在最后打印一个新行,所以我的输出不在一行。 有没有办法做到这一点?

写主机-NoNewline“启用functionXYZ .......”

不幸的是,正如在几个答案和评论中指出的, Write-Host可能是危险的,不能通过pipe道传输到其他进程, Write-Output没有-NoNewline标志。

但是这些方法是显示进度的“nix”方式,“PowerShell”方法似乎是Write-Progress :它在PowerShell窗口的顶部显示一个进度信息栏,可以从PowerShell 3.0开始,详情请参阅手册 。

 # Total time to sleep $start_sleep = 120 # Time to sleep between each notification $sleep_iteration = 30 Write-Output ( "Sleeping {0} seconds ... " -f ($start_sleep) ) for ($i=1 ; $i -le ([int]$start_sleep/$sleep_iteration) ; $i++) { Start-Sleep -Seconds $sleep_iteration Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) ( " {0}s ..." -f ($i*$sleep_iteration) ) } Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) -Completed "Done waiting for X to finish" 

并以OP的例子:

 # For the file log Write-Output "Enabling feature XYZ" # For the operator Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... " ) Enable-SPFeature... # For the operator Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... Done" ) # For the log file Write-Output "Feature XYZ enabled" 

虽然它可能不适用于你的情况(因为你提供丰富的输出给用户),创build一个可以用来追加输出的string。 输出时,输出string。

当然,忽略这个例子在你的情况下是愚蠢的,但在概念上是有用的:

 $output = "Enabling feature XYZ......." Enable-SPFeature... $output += "Done" Write-Output $output 

显示:

 Enabling feature XYZ.......Done 

你根本无法得到PowerShell来省略这些麻烦的换行符…没有脚本或cmdlet。 当然, 写主机是绝对的废话,因为你不能redirect/pipe道从它!

不过,你可以编写自己的EXE文件来做到这一点,我解释了如何在堆栈溢出的问题如何在PowerShell中输出的东西

要写入文件,可以使用字节数组。 以下示例创build一个空的ZIP文件,您可以将文件添加到该文件中:

 [Byte[]] $zipHeader = 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 [System.IO.File]::WriteAllBytes("C:\My.zip", $zipHeader) 

或使用:

 [Byte[]] $text = [System.Text.Encoding]::UTF8.getBytes("Enabling feature XYZ.......") [System.IO.File]::WriteAllBytes("C:\My.zip", $text) 

我碰到的问题是,使用PowerShell v2时,写入输出实际上会突破输出,至less是stdout。 我试图写一个XML文本到标准输出没有成功,因为它将很难包装在字符80。

解决方法是使用

 [Console]::Out.Write($myVeryLongXMLTextBlobLine) 

这在PowerShell v3中不是问题。 写输出似乎在那里正常工作。

根据PowerShell脚本的调用方式,您可能需要使用

 [Console]::BufferWidth =< length of string, eg 10000) 

在写入标准输出之前。

是的,因为其他答案有状态,所以不能用写入输出来完成。 在PowerShell失败的情况下,转向.NET,这里甚至有一些.NET的答案,但它们比他们需要的更复杂。

只要使用:

 [Console]::Write("Enabling feature XYZ.......") Enable-SPFeature... Write-Output "Done" 

这不是最纯粹的PowerShell,但它的工作原理。

shufler的答案是正确的。 换句话说:不是使用ARRAY FORM将值传递给Write-Output,

 Write-Output "Parameters are:" $Year $Month $Day 

或者通过对写入输出的多次调用等效,

 Write-Output "Parameters are:" Write-Output $Year Write-Output $Month Write-Output $Day Write-Output "Done." 

首先将您的组件连接成STRING VARIABLE:

 $msg="Parameters are: $Year $Month $Day" Write-Output $msg 

这将防止多次调用Write-Output(或ARRAY FORM)引起的中间CRLF,但当然不会抑制Write-Output命令行的最终CRLF。 为此,您将不得不编写自己的命令行开关,使用此处列出的其他令人费解的解决方法之一,或者等到Microsoft决定支持Write-Output的-NoNewline选项。

您也可以通过使用写主机来满足您向控制台提供文本进度表的要求(即“….”),而不是写入日志文件。 您可以通过将msg文本收集到用于写入日志的variables中并使用Write-Host向控制台提供进度来完成这两个操作。 这个function可以结合到你自己的commandlet中,以实现最大的代码重用。

在PowerShell中似乎没有办法做到这一点。 所有以前的答案都是不正确的,因为它们不像Write-Output那样工作,但更像是Write-Host ,它不存在这个问题。

closures解决scheme似乎使用Write-Host-NoNewLine参数。 你不能pipe这一般是一个问题,但有一种方法可以像Write-Host => Export to一个文件中所描述的那样覆盖这个函数,所以你可以很容易地让它接受输出文件的参数。 这还不是一个好的解决scheme。 随着Start-Transcript这是更有用的,但该cmdlet有本地应用程序的问题。

Write-Output在一般情况下根本无法做到你所需要的。

简化到FrinkTheBrave的回应:

 [System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent) 

以下将把光标放回到前一行的开头。 这取决于你把它放在正确的水平位置(使用$ POS.X横向移动):

 $pos = $host.ui.RawUI.get_cursorPosition() $pos.Y -= 1 $host.UI.RawUI.set_cursorPosition($Pos) 

你目前的输出是27个空格,所以$ pos.X = 27可能工作。

它可能不是非常优雅,但它确实是OP所要求的。 请注意,ISE使用StdOut混淆,所以不会有输出。 为了看到这个脚本的工作,它不能在ISE内运行。

 $stdout=[System.Console]::OpenStandardOutput() $strOutput="Enabling feature XYZ... " $stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length) Enable-SPFeature... $strOutput="Done" $stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length) $stdout.Close() 

你绝对可以做到这一点。 写输出有一个名为“ NoEnumerate ”的标志本质上是一样的东西。