Как вывести текст без перевода строки в PowerShell? - PullRequest
127 голосов
/ 09 октября 2010

Я хочу, чтобы мой скрипт PowerShell печатал что-то вроде этого:

Enabling feature XYZ......Done

Сценарий выглядит примерно так:

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

Но Write-Output всегда печатает новую строку в конце, поэтому мой вывод не находится на одной строке. Есть ли способ сделать это?

Ответы [ 15 ]

142 голосов
/ 09 октября 2010

Write-Host -NoNewline "Enabling feature XYZ......."
34 голосов
/ 15 сентября 2015

К сожалению, как отмечалось в нескольких ответах и ​​комментариях, 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"

И взять пример ОП:

# 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"
14 голосов
/ 14 февраля 2013

Хотя это может не сработать в вашем случае (поскольку вы предоставляете информативный вывод пользователю), создайте строку, которую можно использовать для добавления вывода.Когда пришло время вывести его, просто выведите строку.

Конечно, не обращая внимания на то, что этот пример глуп в вашем случае, но полезен в концепции:

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

Отображается:

Enabling feature XYZ.......Done
5 голосов
/ 08 июня 2016

Да, так как другие ответы имеют состояния, это нельзя сделать с помощью записи-вывода. В случае сбоя PowerShell обращайтесь к .NET, здесь есть даже несколько ответов .NET, но они более сложные, чем должны быть.

Просто используйте:

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

Это не самый чистый PowerShell, но он работает.

2 голосов
/ 05 января 2018

Write-Host ужасен, разрушитель миров, но вы можете использовать его только для отображения прогресса пользователя при использовании Write-Output для регистрации (не то, что ОП запрашивал запись в журнал).

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" }

2 голосов
/ 25 марта 2016

Кажется, что в PowerShell этого не сделать.Все предыдущие ответы не верны, потому что они не ведут себя так, как ведет себя Write-Output, но больше похожи на Write-Host, у которого в любом случае такой проблемы нет.с параметром -NoNewLine.Вы не можете передать это, что является проблемой в целом, но есть способ переопределить эту функцию, как описано в Write-Host => Экспорт в файл , поэтому вы можете легкоон принимает параметр для выходного файла.Это все еще далеко от хорошего решения.С Start-Transcript это более удобно, но у этого командлета есть проблемы с нативными приложениями.

Write-Output просто не может делать то, что вам нужно в общем контексте.

2 голосов
/ 04 июля 2014

Проблема, с которой я столкнулся, заключалась в том, что запись-вывод на самом деле ломает вывод при использовании PowerShell v2, по крайней мере, для stdout.Я безуспешно пытался написать XML-текст на стандартный вывод, потому что он был бы жестко обернут в символ 80.

Обходной путь должен был использовать

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

Это не было проблемой в PowerShellv3.Кажется, что запись-вывод там работает должным образом.

В зависимости от того, как вызывается скрипт PowerShell, вам может потребоваться использовать

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

перед записью в стандартный вывод.

2 голосов
/ 06 марта 2012

Для записи в файл вы можете использовать байтовый массив. В следующем примере создается пустой 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)
1 голос
/ 23 августа 2015

Ответ Шуфлера правильный. Другими словами: вместо передачи значений в Write-Output с помощью ARRAY FORM,

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

или эквивалент несколькими вызовами для записи-вывода,

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

сначала объедините ваши компоненты в переменную STRING:

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

Это предотвратит промежуточные CRLF, вызванные многократным вызовом Write-Output (или ARRAY FORM), но, конечно, не подавит окончательный CRLF командлета Write-Output. Для этого вам придется написать свой собственный командлет, использовать один из других запутанных обходных путей, перечисленных здесь, или подождать, пока Microsoft не решит поддержать опцию -NoNewline для записи-вывода.

Ваше желание предоставить текстовый индикатор прогресса на консоль (т. Е. "....") в отличие от записи в файл журнала также должно быть удовлетворено с помощью Write-Host. Вы можете сделать это, собирая текст сообщения в переменную для записи в журнал И используя Write-Host для обеспечения прогресса на консоли. Эта функциональность может быть объединена в ваш собственный командлет для максимального повторного использования кода.

1 голос
/ 28 сентября 2013

Упрощение ответа FrinkTheBrave:

[System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...