PowerShell에서 줄 바꿈없이 텍스트를 어떻게 출력합니까?


145

PowerShell 스크립트가 다음과 같이 인쇄되기를 원합니다.

Enabling feature XYZ......Done

스크립트는 다음과 같습니다.

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

그러나 Write-Output항상 줄 바꿈을 인쇄하여 출력이 한 줄에 있지 않습니다. 이것을 할 수있는 방법이 있습니까?


답변:


165

Write-Host -NoNewline "기능 XYZ 사용 가능 .."


62
OP의 예는 특히 Write-Output와 (과) 기능이 크게 다른을 사용하기 때문에 다운 보트되었습니다 Write-Host. 독자는 답을 복사 / 붙여 넣기 전에이 큰 차이를 기록해야합니다.
NathanAldenSr

5
@NathanAldenSr에 동의합니다. Write-Host는 파일 등으로 출력하려고하면 도움이되지 않습니다.
stevethethread

6
Write-Host거의 정답이 아닙니다. >/dev/ttyUnixland 에서하는 것과 같습니다 .
Mark Reed

2
Write-Progress경우에 따라 적절할 수 있습니다 (아래 예 참조).
토마스

12
OP의 예에서 구체적으로을 사용하기 때문에 하향 조정되었습니다 Write-Output. 매개 변수 Write-Output가 없습니다 -NoNewLine.
Slogmeister Extraordinaire

49

불행히도 여러 답변과 의견에서 언급했듯이 Write-Host위험 할 수 있으며 다른 프로세스로 파이프 될 수 없으며 플래그 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"

3
나는 이것이 상태를 보여주는 가장 좋은 해결책이라고 생각합니다. 로그 또는 무언가가 필요한 경우 Write-Output의 줄 바꿈으로 생활해야합니다.
fadanner

1
프로그레시브 디스플레이 포인트는 라이브 설치를위한 "공상적"일 뿐이며 로그 파일에 표시 할 필요가 없습니다. "무엇을 시작"하고 "무슨 일을"합니다
Thomas

13

사용자에게 유익한 출력을 제공하기 때문에 귀하의 경우에는 작동하지 않을 수 있지만 출력을 추가하는 데 사용할 수있는 문자열을 만드십시오. 출력 할 때 문자열 만 출력하십시오.

물론이 예제가 어리석지 만 개념에는 유용하다는 것을 무시하십시오.

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

디스플레이 :

Enabling feature XYZ.......Done

1
이는 제공된 특정 예에서 작동 할 수 있지만에 의해 생성 된 추가 줄 바꿈이 여전히 Write-Output있습니다. 합리적인 해결책이지만 해결책은 아닙니다.
Slogmeister Extraordinaire

Write-Output은 항상 끝에 줄 바꿈을 출력합니다. 이 cmdlet와 그 주위에 방법이 없습니다
shufler

7
기능이 설치된 후 전체 출력이 표시되므로 이것은 중요하지 않습니다.
majkinetor

10
때문에,이 질문에 1 개 이상의 upwote을주는 사람, 이해하지 못하는 이 이후 시점없는 기능이 설치된 후 전체 출력이 나타납니다
maxkoryukov

1
"물론이 예제가 어리석지 만 개념에는 유용하다는 것을 무시합니다."
shufler

6

예, 다른 답변에는 상태가 있으므로 Write-Output으로 수행 할 수 없습니다. PowerShell이 ​​실패하면 .NET으로 전환하십시오. 여기에 .NET 답변이 몇 개 있지만 필요한 것보다 더 복잡합니다.

그냥 사용하십시오 :

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

가장 순수한 PowerShell은 아니지만 작동합니다.


5
Write-Host사람들이 기대하지 않는 것을 제외하고는 이와 같이 작동하기 때문에 다운 투표되었습니다 .
JBert

4

파일에 쓰려면 바이트 배열을 사용할 수 있습니다. 다음 예제는 파일을 추가 할 수있는 빈 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)

대단한 예입니다!
Peter Mortensen 2016 년

2

FrinkTheBrave의 답변 단순화 :

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

이것은 전혀 질문에 대답하지 않습니다.
NathanAldenSr

2
그러나 정확히 내가 찾은 것과 질문의 제목에서 기대 한 것입니다.
Patrick Roocks

2

필자가 겪은 문제는 PowerShell v2를 사용할 때 Write-Output이 실제로 stdout에 출력을 줄 바꿈한다는 것입니다. 문자 80으로 줄 바꿈되기 때문에 XML 텍스트를 성공하지 않고 stdout에 쓰려고했습니다.

해결 방법은

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

PowerShell v3에서는 문제가되지 않았습니다. 쓰기 출력이 제대로 작동하는 것 같습니다.

PowerShell 스크립트가 호출되는 방식에 따라 사용해야 할 수도 있습니다.

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

stdout에 쓰기 전에


2
Write-Host처럼 동작하지만 최악입니다. 예를 들어 파일로 파이프 할 수 없습니다.
majkinetor

2

PowerShell 에서이 작업을 수행 할 수있는 방법이없는 것 같습니다. 이전의 모든 대답은 정확하지 않습니다. 왜냐하면 행동 방식 Write-Output이 아니라Write-Host 어쨌든이 문제가없는 것입니다.

닫기 솔루션은 매개 변수 Write-Host와 함께 사용 하는 것 같습니다 -NoNewLine. 일반적으로 문제가되는 이것을 파이프 할 수는 없지만 Write-Host => Export to a file에 설명 된 대로이 함수를 재정의하는 방법이 있으므로 출력 파일의 매개 변수를 쉽게 받아 들일 수 있습니다. 이것은 여전히 ​​좋은 해결책과는 거리가 멀다. 이를 사용 Start-Transcript하면 더 유용하지만 해당 cmdlet에는 기본 응용 프로그램에 문제가 있습니다.

Write-Output단순히 일반적인 상황에서 필요한 것을 할 수 없습니다.


2

Write-Host세계의 파괴자이지만 끔찍하지만 Write-Output로그 를 사용 하는 동안 사용자에게 진행 상황을 표시하는 데 사용할 수 있습니다 (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"
}

진행 상황을 표시해야 할 필요성에 따라에도 있습니다 Write-Progress.
chwarr

1

당신은 단순히 그 성가신 개행을 생략하기 위해 PowerShell을 얻을 수 없습니다 ... 스크립트 또는 cmdlet이 없습니다. 물론 Write-Host 는 절대 넌센스입니다. 리다이렉트 / 파이프 할 수 없기 때문입니다!

그럼에도 불구하고 직접 EXE 파일을 작성하여 스택 오버플로 질문 PowerShell에서 무언가를 출력 하는 방법에서 수행 한 방법을 설명합니다 .


2
잘못된 정보입니다. Shay와 Jay가 훌륭하게 대답 했으므로 -NoNewline을 첫 번째 인수로 추가하십시오.
David at HotspotOffice

2
어쩌면 그것은 지금 @DavidatHotspotOffice의 경우일지도 모르지만 1 년 전에 작동하지 않는 윈도우 박스를 마지막으로 만졌을 때 Write-Host에서 리디렉션 / 파이프 할 수 없었습니다. 공정하게 말해서 POSH 나 .NET에 대한 인내심이 조금도 없었기 때문에 몇 달이 지나서 유닉스 땅으로 돌아 왔습니다. 웃긴
samthebest

3
@DavidatHotspotOffice-실제로 그는 정확합니다. Write-Output에 대한 "NoNewLine"인수는 없습니다. 이것은 원래의 질문에 대한 것입니다. Write-Output을 사용하는 데는 몇 가지 이유가 있습니다. 따라서이 답변이 의미가 있습니다. jsnover.com/blog/2013/12/07/write-host-considered-harmful
James Ruskin

질문이 "PowerShell에서"솔루션을 요청하기 때문에 다운 보트되었습니다. 외부 EXE를 작성하는 것은 "PowerShell"이 아닙니다.
Slogmeister Extraordinaire

1
@SlogmeisterExtraordinaire PowerShell에서는 불가능하므로 내 대답은 합리적입니다. 세계가 최악의 쉘을 가진 세계 최악의 운영 체제와 작업해야하기 때문에 슬프기 때문에 방금 다운 투표.
samthebest

1

shufler의 답변이 맞습니다. 다른 방법으로 말하면 ARRAY FORM을 사용하여 값을 Write-Output에 전달하는 대신,

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

또는 Write-Output을 여러 번 호출하여 이에 해당하는

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을 여러 번 호출하여 발생하는 중간 CRLF (또는 ARRAY FORM)가 방지되지만 물론 Write-Output 커맨드 렛의 최종 CRLF는 억제되지 않습니다. 이를 위해서는 자신 만의 커맨드 렛을 작성하거나 여기에 나열된 다른 복잡한 해결 방법 중 하나를 사용하거나 Microsoft가 다음을 지원하기로 결정할 때까지 기다려야합니다.-NoNewline Write-Output 옵션 합니다.

로그 파일에 쓰지 않고 콘솔에 텍스트 진행률 미터 (예 : "....")를 제공하려는 경우 Write-Host를 사용하여 만족해야합니다. msg 텍스트를 로그에 쓸 변수로 수집하고 Write-Host를 사용하여 콘솔에 진행 상황을 제공하여 둘 다 수행 할 수 있습니다. 이 기능은 코드 재사용을 극대화하기 위해 자신의 커맨드 렛에 결합 할 수 있습니다.


나는 다른 사람들 보다이 대답을 훨씬 선호합니다. 객체의 속성을 호출하는 경우 따옴표로 묶을 수 없으므로 다음과 같이 사용했습니다. Write-Output ($ msg = $ MyObject.property + "포함 할 일부 텍스트"+ $ Object.property)
Lewis

2
@Lewis 확실히 문자열 안에 객체 속성을 포함시킬 수 있습니다! 변수를 둘러싸려면 $ () 표현식을 사용하십시오. 예 : "$ ($ MyObject.Property) $ ($ Object.property)를 포함시키려는 일부 텍스트"
shufler

이것은 제공된 특정 예에서 작동 할 수 있지만에 의해 생성 된 추가 줄 바꿈이 여전히 Write-Output있습니다. 마지막으로 작성된 것이므로 볼 수 없습니다. 합리적인 해결책이지만 해결책은 아닙니다. 후행 줄 바꿈을 처리 할 수없는 결과 출력을 소비하는 것이있을 수 있습니다.
Slogmeister Extraordinaire

1
정확하지 않습니다. 단일 명령으로 솔루션을 수행 할 수 없습니다.
majkinetor

이것은 문제를 다루지 않습니다. 로그 파일 출력에는 시도한 작업이 표시되어 오류를보고 추적 할 수 있습니다. 연결은 그것을 달성하지 못합니다.
durette

0

다음은 이전 행의 시작 부분에 커서를 다시 배치합니다. 올바른 수평 위치 ($ pos.X를 사용하여 옆으로 이동)에 배치하는 것은 사용자의 책임입니다.

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

현재 출력은 27 칸 이상이므로 $ pos.X = 27 이 작동 할 수 있습니다.


이것은 파일 출력과 관련이 없습니다.
Slogmeister Extraordinaire

그것도 나쁘지 않습니다. 또한 올바른 출력을 생성 할 수 $pos.X있습니다. 문제는 파일로 파일을 파이프하면 별도의 두 줄이 나타납니다.
majkinetor

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()

1
정확하지 않습니다. 파일에 넣고 파이프를 출력하면 아무것도 나타나지 않습니다.
majkinetor

파일로의 배관은 OP가 요청한 것이 아닙니다. 예, [System.Console]파일로 리디렉션 할 수 없습니다.
Slogmeister Extraordinaire

0

나는 속 였지만 이것이 모든 요구 사항을 해결하는 유일한 대답이라고 생각합니다. 즉, 후행 CRLF를 피하고 그 동안 다른 작업을 완료 할 수있는 장소를 제공하며 필요에 따라 표준 출력으로 올바르게 리디렉션합니다.

$c_sharp_source = @"
using System;
namespace StackOverflow
{
   public class ConsoleOut
   {
      public static void Main(string[] args)
      {
         Console.Write(args[0]);
      }
   }
}
"@
$compiler_parameters = New-Object System.CodeDom.Compiler.CompilerParameters
$compiler_parameters.GenerateExecutable = $true
$compiler_parameters.OutputAssembly = "consoleout.exe"
Add-Type -TypeDefinition $c_sharp_source -Language CSharp -CompilerParameters $compiler_parameters

.\consoleout.exe "Enabling feature XYZ......."
Write-Output 'Done.'

0
$host.UI.Write('Enabling feature XYZ.......')
Enable-SPFeature...
$host.UI.WriteLine('Done')

0

원하는 o / p : 기능 XYZ 활성화 중 ... 완료

아래 명령을 사용할 수 있습니다

$ a = "기능 XYZ 활성화"

쓰기 출력 "$ a ...... 완료"

따옴표 안에 변수와 문장을 추가해야합니다. 이것이 도움이되기를 바랍니다 :)

감사합니다 Techiegal


쓰기 출력은 개체를 파이프 라인에 배치하는 데 선호됩니다. 텍스트 표시의 경우 Write-Host가 자주 사용되며 최근에는 Write-Information이 정보 스트림에 쓰는 데 사용됩니다.
논리도

0

여기에 너무 많은 답변이 있습니다. 아무도 아래로 스크롤하지 않습니다. 어쨌든 끝에 다음과 같이 줄 바꿈없이 텍스트를 작성하는 솔루션도 있습니다.

인코딩 된 파일 출력 :

  # a simple one liner
  "Hello World, in one line" | Out-File -Append -Encoding ascii -NoNewline -FilePath my_file.txt;

  # this is a test to show how it works
  "Hello World".Split(" ") | % { "_ $_ _" | Out-File -Append -Encoding ascii -NoNewline -FilePath my_file.txt; }

콘솔 출력 :

  # a simple one liner
  "Hello World, in one line" | Write-Host -NoNewline;

  # this is a test to show how it works
  "Hello World".Split(" ") | % { "_ $_ _" | Write-Host -NoNewline; }

-3

당신은 절대적으로 이것을 할 수 있습니다. Write-Output에는 본질적으로 동일한 " NoEnumerate " 라는 플래그 가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.