2010-10-09 514 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" }

相關問題