Как подставлять значения переменных в строках с Powershell


19 августа 2020


Подстановка переменных в строках Powershell на примерах

В Powershell есть много методов работы со строками. Один из самых популярных способов - это использование переменных в строках с последующей подменой. Такой метод часто называют подстановкой или форматированием. В этой статье будут рассмотрены все способы таких операций на примерах.

Сложение

Самый простой способ сложения значения переменной и строки относится к конкатенации. Мы просто используем знак сложения:

$name = 'Алексею'
$mail = 'Отправить сообщение ' + $name

Сложение строк в Powershell и конкатенация

Такой же способ сработает с числом и несколькими переменными:

$name = 'Алексею'
$subject = 'Отправить сообщение '
$time = 13
$mail = $subject + $name + ' ' + $time

Сложение строк и чисел в Powershell и конкатенация

 

Подстановка переменных

Самый удобный способ подстановки переменных - это их использование в строках. Именно этот способ несет основное отличие между одинарными и двойными кавычками. Если мы будем подставлять переменную с одинарными кавычками - значение будет интерпретироваться как просто строка.

$year = '2019'
$text = "Сотрудник родился в $year году"

Подстановка переменных в Powershell 

Команды

Такой способ подстановок мы можем использовать и для команд, но при вызове свойств или методов можем получить некорректные данные:

$date = Get-Date
$message = "Мы живем в $date.year году"

Вызов свойств внутри строки и экранирование в Powershell

Такая ошибка происходит из-за интерпретации точки рядом с переменной. Powershell относит эту точку к продолжению строке. Способ обойти эту проблему - использование скобок (аналогичное можно сделать и в Bash):

$date = Get-Date
$message = "Мы живем в $($date.year) году"

Вызов свойств внутри строки Powershell 

Используя этот способ мы можем и вызывать команды аналогично следующему примеру:

$message = "Последний HotFix был установлен $((Get-HotFix | select -First 1).InstalledOn)"

Вызов свойств внутри строки Powershell

Слитное написание переменных и строк

При попытке выполнения следующей подстановки мы не получим ожидаемый результат:

$end = 'от'
Write-Host "Зол$endая"

Слитное написание переменной и строки в Powershell

В примере выше просто нельзя идентифицировать начало и конец переменной. Для исправления таких ситуаций мы можем использовать фигурные скобки, а так же  и методы описанные выше:

$end = 'от'
Write-Host "Зол${end}ая"
Write-Host "Зол$($end)ая"

Слитное написание переменной и строки в Powershell

Отложенное развертывание значений переменных

Если мы используем переменную в строке до ее объявления мы получим, отчасти, пустой ответ:

$text = "Directory: $dir"
$dir = "C:\"

Отложенное развертывание переменной в Powershell

Метод .NET .InvokeCommand.ExpandString позволяет выполнить замену переменной до объявления строки в которой она находится. Основная проблема работы с этим методом в том, что он работает в рамках видимости переменных. Мы должны будем передать методу только строку, которую захотим использовать:

$text = "Directory: $dir"
$dir = "C:\"
$result = $ExecutionContext.InvokeCommand.ExpandString($text)

Отложенное развертывание переменной в Powershell

 

Форматирование

Форматирование - это еще один способ подстановки значений. Мы можем использовать методы как Powershell, так и .NET:

# Метод Powershell
'Размер диска {0}Gb. Использовано {1}Gb' -f '10','8'

# Метод .Net
[string]::Format('Размер диска {0}Gb. Использовано {1}Gb', '10','8')

Форматирование строк в Powershell

Для подстановки значений используются массивы (в случае выше это массив из 10 и 8). Первое значение массива имеет индекс, который равен 0. Сам индекс - это порядок нумерации и в большинстве языков он начинается с 0. Когда в строках мы указываем {0} мы буквально говорим, что оно будет равно первому значению массива. 

Аналогично пример, но тут мы пропустим одно значение с индексом 1:

$array = @('10Gb', 'Неиспользуемое значение', '8Gb')
'Размер диска {0}. Использовано {2}' -f $array

Форматирование строк и хэш таблиц в Powershell

Есть так же встроенные методы форматирования, которые позволяют преобразовать значения внутри строки. Например мы можем изменить формат даты с в вид день-месяц-число:

# Смотрим формат вывода даты
Get-Date
# Преобразуем дату внутри
"{0:dd-MM-yyyy}" -f (Get-Date)

Форматирование даты в Powershell 

 

Преобразование данных в строки

Вам может понадобится преобразовать массив в строку. Для таких операций, во многих языках, существует оператор join. Единственное что мы должны указать - это разделитель, который будет использоваться для создания строки:

$array = @('Я', 'пошел', 'на работу')
$array -join ' '

Перевод массива в строку Powershell 

В примере выше был использован пробел в качестве разделителя, так как именно пробелы сделают предложения читаемым. Так же часто бывает нужно использовать запятые ',' или знак обозначающий перенос строк "`n". Перенос строк используется чаще всего там, где планируется импорт и экспорт файлов и тут так же важен тип кавычек:

$array = @('Я', 'пошел', 'на работу')
$array -join "`n"

Перевод массива в строку Powershell с переносом  

Преобразовать массив в строку, не указывая разделителя, так же можно использовав метод .Net:

$letters = @('a','b','c')
[string]::Concat($letters)

Сложение значений массива в строку Powershell

Строки - это бывшие массивы

Если посмотреть поверхностно на пример ниже, то мы увидим только скрипт добавляющий случайные значения к строке:

$str = "Случайные числа: "
foreach ($num in 1..10){
 $random_num = Get-Random -Minimum 1 -Maximum 100
 $str += ' '+$random_num 
}

Строки и массивы Powershell

На самом деле, при каждой итерации (цикле), у нас создается массив из 2 элементов, а затем он объединяется. Минус такого подхода в том, что объединение происходит каждую итерацию, а не единожды. Такой минус будет ощутим при больших данных. Если для вас этот момент важен - вы можете использовать класс .NET StringBuilder, который объединит значения только после цикла:

# Создаем объект класса
$net_class = New-Object -TypeName "System.Text.StringBuilder"
# Добавляем к нему первую строку
[void]$net_class.Append("Случайные числа: ")
foreach ($num in 1..10){
 $random_num = Get-Random -Minimum 1 -Maximum 100
 # Добавляем в объект класса случайное значение
 [void]$net_class.Append("$random_num ")
}
# Используем метод для объединения всех значений
$str =$net_class.ToString()

Ускорение работы строк и  массивов в Powershell

 

Преобразование путей

При работе с путями мы так же используем строки. Есть командлет, который позволяет соединять части путей:

$directory = 'System32'
Join-Path -Path 'C:\Windows' -ChildPath $directory

Преобразование системных путей в Powershell 

Плюс этой команды в том, что он будет работать с любыми видами слэшей преобразовывая их в корректный формат:

Преобразование системных путей в Powershell

 

Поиск и замена

Основной способ замены значений в строках - это использование параметра '-replace':

$job = 'Зовите меня Димон'
$job -replace 'Димон','Вован'

Замена значений в строках Powershell

Если вы используете какие-то шаблоны для конфигурации сервисов хороший способ автоматизировать этот процесс - использовать явные идентификаторы, например "#IPADDRESS#". При надобности вы сможете найти это значение в тексте и заменить его:

$job = '
ipaddr: #IPADRESS#
DNS1: #DNS1#
'
$job -replace '#IPADRESS#','192.168.3.1' -replace '#DNS1#','8.8.8.8'

Использование шаблонов с подстановкой значений в Powershell

Еще один из способов такой подстановки - использование хэш таблиц (массив из ключей и значений). Такой способ подойдет, если вы используете множество идентификаторов. Мы объявляем хэш таблицу с нужными значениями, а через цикл проходим и применяем их к тексту:

$hash_table = @{
    IPAddress='192.168.3.2';
    DNS1='8.8.8.8';
    Gateway='192.168.3.1';
}

$job = '
ipaddr: #IPADDRESS#
DNS1: #DNS1#
GATE: #Gateway#
'

foreach($value in $hash_table.GetEnumerator()){
  $ff = '#{0}#' -f $value.key
  $job = $job -replace $ff, $value.Value
}

Использование шаблонов с подстановкой значений в Powershell

...

Теги: #powershell


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.