2010-10-09 524 views
104

我希望我的PowerShell脚本打印是这样的:如何在PowerShell中输出不带换行符的文本?

Enabling feature XYZ......Done 

脚本看起来是这样的:

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

Write-Output总是在最后打印新行,所以我的输出ISN”在一条线上。有没有办法做到这一点?

+0

[在写入输出避免换行(http://stackoverflow.com/questions/6150255/avoiding-newline-in-write-output)的可能的复制 – 2016-12-02 02:39:21

回答

115

 
Write-Host -NoNewline "Enabling feature XYZ......." 

+31

不同的是使用写主机通常是错误的命令 – cmcginty 2014-05-24 01:13:14

+32

因为OP的例子特别使用了'Write-Output',它的功能与'Write-Host'有很大不同。在复制/粘贴答案之前,读者应该注意这个重大缺陷。 – NathanAldenSr 2015-03-07 02:50:28

+4

我同意@NathanAldenSr,如果您尝试输出到文件等,Write-Host不起作用。 – stevethethread 2015-06-03 15:22:34

2

写信给你可以使用一个字节数组的文件。下面的示例创建一个空的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) 
+0

这是一个很棒的例子! – 2017-06-04 12:07:16

2

你根本无法获得PowerShell来忽略那些讨厌的换行符......没有脚本或者cmdlet。当然,Write-Host是绝对的废话,因为你不能从它重定向/管道!

不过,你可以编写自己的EXE文件做这正是我解释了如何在堆栈溢出问题How to output something in PowerShell做。

+2

信息不正确。正如Shay和Jay出色地回答,只需添加-NoNewline作为第一个参数。 – 2013-11-18 16:30:20

+2

也许现在的情况是@DavidatHotspotOffice,但是当我上次碰到一个没有工作的窗口框(一年前)时,无法从写主机重定向/管道。平心而论,我对POSH或.NET毫无耐心,几个月后我辞职回到unix的土地。 [funny](http://thecodinglove.com/post/66696568857/when-i-try-to-use-powershell-after-not-using-it-for-a) – samthebest 2013-11-23 10:01:26

+3

@DavidatHotspotOffice - 其实他是对的。 Write-Output没有“NoNewLine”的说法,这是最初的问题。看起来,使用Write-Output有一些很好的理由 - 所以这个答案很有意义。 http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/ – 2014-03-07 09:17:34

17

虽然它可能不适用于您的情况(因为您向用户提供信息输出),请创建一个可用于追加输出的字符串。输出时,只需输出字符串即可。

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

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

显示:

Enabling feature XYZ.......Done 
+1

这可以在所提供的特定示例中工作,但是仍然有一个额外的由“Write-Output”生成的换行符。合理的解决方法,但不是解决方案。 – 2016-02-26 15:23:45

+0

写入输出总是在最后输出一个换行符。使用此cmdlet无法解决此问题 – shufler 2016-02-26 17:05:59

+1

这不是重点,因为在安装该功能部件后会显示整个输出。 – majkinetor 2016-03-25 11:03:47

0

简化到FrinkTheBrave的回应:

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

这根本不回答问题。 – NathanAldenSr 2015-03-07 02:51:00

+1

但这正是我所搜索的内容以及我对问题标题的期望。 – 2015-03-20 09:04:24

2

的我碰到的问题是,使用PowerShell v2时,写输出实际上会突破输出,至少要标准输出。我试图写一个XML文本没有成功到stdout,因为它会在人物80

被硬缠的解决方法是使用

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

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

根据PowerShell脚本是如何被调用,您可能需要使用

[Console]::BufferWidth =< length of string, e.g. 10000) 

你写入stdout之前。

+1

表现像写主机,但最差。例如,你不能将其传送到文件。 – majkinetor 2016-03-25 11:06:13

0

以下操作将光标放回到上一行的开头。这取决于你把它放在正确的水平位置(使用$ pos。X向侧面移动):

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

您的电流输出为27位结束了,所以$ pos.X = 27可能会奏效。

+0

这与文件输出无关。 – 2016-02-26 15:32:05

+0

它也没有那么糟糕。如果您也执行'$ pos.X',它可以产生正确的输出。问题是,如果你将它管到一个文件中,会出现两条单独的行。 – majkinetor 2016-03-25 11:08:57

1

shufler的答案是正确的。换句话说:不是值传递给写输出使用数组形式的,

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

或多个呼叫相当于写输出,

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

串连您的组件集成到一个字符串变量第一:

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

这将防止因调用写输出多次(或阵列状)的中间体CRLFs,但当然不会抑制的最终CRLF写入输出命令行。为此,您必须编写自己的命令行开关,使用此处列出的其他令人费解的解决方法之一,或者等到Microsoft决定支持用于写入输出的-NoNewline选项。

使用写主机还可以满足您希望向控制台提供文本进度表(即“....”)而不是写入日志文件的需求。您可以通过将msg文本收集到用于写入日志的变量中并使用Write-Host向控制台提供进度来完成这两项操作。此功能可以组合到您自己的命令行中,以实现最大程度的代码重用。

+0

我比其他人更喜欢这个答案。如果你调用对象的属性,你不能用引号将它们括起来,所以我使用了:Write-Output($ msg = $ MyObject.property +“我想包含一些文本”+ $ Object.property) – Lewis 2015-11-02 13:16:30

+0

@Lewis你当然可以在一个字符串中包含对象属性!使用$()表达式来包围任何变量,例如“$($ MyObject.Property)我想包含一些文本$($ Object.property)” – shufler 2015-11-07 21:22:47

+0

很高兴知道,谢谢! – Lewis 2015-12-02 14:40:10

20

不幸的是,正如在几个答案和评论中指出的那样,Write-Host可能很危险,不能通过管道连接到其他进程,并且Write-Output没有-NoNewline标志。

但是,这些方法是显示进度的“* nix”方法,“PowerShell”方法似乎是Write-Progress:它在PowerShell窗口的顶部显示一个条形图,包含进度信息,可从PowerShell 3.0详情请咨询see manual

# 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" 
+1

我认为这是显示状态的最佳解决方案。如果你需要有一个日志或什么你必须生活与写输出的换行。 – fadanner 2017-01-27 08:53:02

+0

一致认为,加上渐进式显示的重点仅仅是对于实时安装来说“很花哨”,在日志文件中没有任何意义:打印“开始做某件事”然后“完成某件事” – Thomas 2017-06-08 20:40:48

0

它可能不是非常优雅,但它不正是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() 
+0

不正确。如果你把它放到一个文件中并且管道的输出没有出现。 – majkinetor 2016-03-25 11:11:47

+0

管道到文件不是OP请求的东西。是的,'[System.Console]'不能被重定向到一个文件。 – 2017-06-07 16:47:09

2

在PowerShell中似乎没有办法做到这一点。所有以前的答案都是不正确的,因为它们不像Write-Output的行为方式那样行事,但更像Write-Host,它无论如何都没有这个问题。

关闭解决方案似乎使用Write-Host-NoNewLine参数。你不能管这一般是一个问题,但有一种方法可以覆盖这个函数,如Write-Host => Export to a file所述,所以你可以很容易地让它接受输出文件的参数。这还不是一个好的解决方案。使用Start-Transcript这更加可用,但该cmdlet在本机应用程序中存在问题。

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

2

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

只需使用:

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

这不是最纯粹的PowerShell的,但它的作品。

+2

Downvoted,因为它的行为就像'Write-Host',除了人们不会期望它。 – JBert 2017-05-30 10:07:43

-2

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

0

写主机是可怕的,世界的驱逐舰,但你可以使用它只是为了向用户显示进度,同时使用写输出记录(而不是OP要求记录)。

Write-Output "Enabling feature XYZ" | Out-File "log.txt" # Pipe to log file Write-Host -NoNewLine "Enabling feature XYZ......." $result = Enable-SPFeature $result | Out-File "log.txt" # You could try{}catch{} an exception on Enable-SPFeature depending on what it's doing if ($result -ne $null) { Write-Host "complete" } else { Write-Host "failed" }

相关问题