Когда требуется вывести в консоль или в файл один блок текста, разделённый на отдельные строки, часто используется последовательный вызов командлетов Write-Host
и Write-Output
, каждый из которых выводит свою строку - часть общего многострочного вывода. Есть ли другие варианты? Предлагаю разобраться.
Для начала, приведу пример того, о чём сказал в самом начале - многострочный вывод текста через вызовы командлетов для каждой строки. В примере в консоль PowerShell будет выводиться сообщение “HELLO”, по одной букве на строку.
H
E
L
L
O
Write-Output 'H'; Write-Output 'E'; Write-Output 'L'; Write-Output 'L'; Write-Output 'O'
Результат в консоли соответствует ожидаемому, однако при взгляде на приведённый фрагмент кода, сразу становится понятно, что его надо и можно оптимизировать. Тот же самый результат можно получить, если передать командлету Write-Output
массив строк (в примере каждая строка в массива содержит только одну букву).
Write-Output 'H', 'E', 'L', 'L', 'O'
Или так, используя конвейер PowerShell.
'H', 'E', 'L', 'L', 'O' | Write-Output
Результат достигнут, но по факту сообщение в консоли всё равно формируется из отдельных строк. Цель - получить многострочный вывод из одной строки.
Символы переноса строки
Для того, чтобы разбить одно длинное сообщение в консоли на отдельные строки, следует использовать символ возврата каретки `r
и символ переноса строки `n
. Вместе они создадут перенос строки и переход к новой строке в многострочном сообщении.
Write-Output "H`r`nE`r`nL`r`nL`n`rO"
Символ возврата каретки и символ переноса строки можно добавить во время объединения строк в одну.
$str = 'H' + '`r`n' + 'E' + '`r`n' + 'L' + '`r`n' + 'L' + '`r`n' + 'O'
Write-Output $str
[Environment]::NewLine
В качестве альтернативы можно обратиться к свойству среды [Environment]::NewLine
. В зависимости от используемой платформы, свойство возвращает символы \r\n
(возврат каретки и перенос строки) для не Unix платформ или символ \n
(перенос строки) для Unix платформ.
$str = 'H' + [Environment]::NewLine + 'E' + [Environment]::NewLine + 'L' + [Environment]::NewLine + 'L' + [Environment]::NewLine + 'O'
Write-Output $str
Для переносимости решения между разными платформами, использование свойства [Environment]::NewLine
будет преимущественным. Для того, чтобы сократить объём кода, можно присвоить значение свойства переменной с коротким именем, затем использовать её.
$nl = [Environment]::NewLine
Write-Output ('H' + $nl + 'E' + $nl + 'L' + $nl + 'L' + $nl + 'O')
Так или иначе, все рассмотренные примеры увеличивают объём кода и усложняют его. Поэтому если в сценарии предполагается вывод объёмного блока многострочного текста, будет удобнее и проще определить, и разметить его заранее.
Here-String
Here-String - это специальная конструкция для определения многострочного строкового значения. Использование Here-String позволяет обойти все сложности, возникающие при работе с многострочными блоками текста, которые были рассмотрены выше.
Для определения многострочного строкового значения Here-String используется специальный синтаксис, включающий открывающую и закрывающую последовательность символов, размещённых на отдельных строках: @'...'@
(одиночные кавычки) или @"..."@
(двойные кавычки).
$msg = @'
Привет, пользователь!
Для продолжения работы выбери вариант:
1. Выполнить сценарий, вывести результат в консоль;
2. Выполнить сценарий, сохранить результат в текстовый файл;
3. Завершить сценарий.
'@
Write-Output $msg
Использование двойных кавычек в синтаксисе Here-String даёт те же возможности, что и использование двойных кавычек при работе с обычными строками PowerShell - Here-String строка становится расширяемой.
$msg = @"
Привет, $([Environment]::UserName)!
Сегодня $(Get-Date -UFormat '%d %B %Y'). До Нового года осталось $(Get-DaysBeforeNewYear) дней.
"@
Write-Output $msg
В этом примере используется рассмотренная ранее функция Get-DaysBeforeNewYear, при помощи которой можно быстро узнать количество дней, оставшихся до наступления Нового года.
Я настоятельно рекомендую не забывать и не принебрегать использованием Here-String в своих сценариях - это удобно, упрощает написание и чтение кода сценариев.
Какой бы вариант не выбрали вы, уверен, что теперь работа с многострочными блоками текста в сценариях, не вызовет сложностей.