В Powershell есть много методов работы со строками. Один из самых популярных способов - это использование переменных в строках с последующей подменой. Такой метод часто называют подстановкой или форматированием. В этой статье будут рассмотрены все способы таких операций на примерах.
Сложение
Самый простой способ сложения значения переменной и строки относится к конкатенации. Мы просто используем знак сложения:
$name = 'Алексею'
$mail = 'Отправить сообщение ' + $name
Такой же способ сработает с числом и несколькими переменными:
$name = 'Алексею'
$subject = 'Отправить сообщение '
$time = 13
$mail = $subject + $name + ' ' + $time
Подстановка переменных
Самый удобный способ подстановки переменных - это их использование в строках. Именно этот способ несет основное отличие между одинарными и двойными кавычками. Если мы будем подставлять переменную с одинарными кавычками - значение будет интерпретироваться как просто строка.
$year = '2019'
$text = "Сотрудник родился в $year году"
Команды
Такой способ подстановок мы можем использовать и для команд, но при вызове свойств или методов можем получить некорректные данные:
$date = Get-Date
$message = "Мы живем в $date.year году"
Такая ошибка происходит из-за интерпретации точки рядом с переменной. Powershell относит эту точку к продолжению строке. Способ обойти эту проблему - использование скобок (аналогичное можно сделать и в Bash):
$date = Get-Date
$message = "Мы живем в $($date.year) году"
Используя этот способ мы можем и вызывать команды аналогично следующему примеру:
$message = "Последний HotFix был установлен $((Get-HotFix | select -First 1).InstalledOn)"
Слитное написание переменных и строк
При попытке выполнения следующей подстановки мы не получим ожидаемый результат:
$end = 'от'
Write-Host "Зол$endая"
В примере выше просто нельзя идентифицировать начало и конец переменной. Для исправления таких ситуаций мы можем использовать фигурные скобки, а так же и методы описанные выше:
$end = 'от'
Write-Host "Зол${end}ая"
Write-Host "Зол$($end)ая"
Отложенное развертывание значений переменных
Если мы используем переменную в строке до ее объявления мы получим, отчасти, пустой ответ:
$text = "Directory: $dir"
$dir = "C:\"
Метод .NET .InvokeCommand.ExpandString позволяет выполнить замену переменной до объявления строки в которой она находится. Основная проблема работы с этим методом в том, что он работает в рамках видимости переменных. Мы должны будем передать методу только строку, которую захотим использовать:
$text = "Directory: $dir"
$dir = "C:\"
$result = $ExecutionContext.InvokeCommand.ExpandString($text)
Форматирование
Форматирование - это еще один способ подстановки значений. Мы можем использовать методы как Powershell, так и .NET:
# Метод Powershell
'Размер диска {0}Gb. Использовано {1}Gb' -f '10','8'
# Метод .Net
[string]::Format('Размер диска {0}Gb. Использовано {1}Gb', '10','8')
Для подстановки значений используются массивы (в случае выше это массив из 10 и 8). Первое значение массива имеет индекс, который равен 0. Сам индекс - это порядок нумерации и в большинстве языков он начинается с 0. Когда в строках мы указываем {0} мы буквально говорим, что оно будет равно первому значению массива.
Аналогично пример, но тут мы пропустим одно значение с индексом 1:
$array = @('10Gb', 'Неиспользуемое значение', '8Gb')
'Размер диска {0}. Использовано {2}' -f $array
Есть так же встроенные методы форматирования, которые позволяют преобразовать значения внутри строки. Например мы можем изменить формат даты с в вид день-месяц-число:
# Смотрим формат вывода даты
Get-Date
# Преобразуем дату внутри
"{0:dd-MM-yyyy}" -f (Get-Date)
Преобразование данных в строки
Вам может понадобится преобразовать массив в строку. Для таких операций, во многих языках, существует оператор join. Единственное что мы должны указать - это разделитель, который будет использоваться для создания строки:
$array = @('Я', 'пошел', 'на работу')
$array -join ' '
В примере выше был использован пробел в качестве разделителя, так как именно пробелы сделают предложения читаемым. Так же часто бывает нужно использовать запятые ',' или знак обозначающий перенос строк "`n". Перенос строк используется чаще всего там, где планируется импорт и экспорт файлов и тут так же важен тип кавычек:
$array = @('Я', 'пошел', 'на работу')
$array -join "`n"
Преобразовать массив в строку, не указывая разделителя, так же можно использовав метод .Net:
$letters = @('a','b','c')
[string]::Concat($letters)
Строки - это бывшие массивы
Если посмотреть поверхностно на пример ниже, то мы увидим только скрипт добавляющий случайные значения к строке:
$str = "Случайные числа: "
foreach ($num in 1..10){
$random_num = Get-Random -Minimum 1 -Maximum 100
$str += ' '+$random_num
}
На самом деле, при каждой итерации (цикле), у нас создается массив из 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()
Преобразование путей
При работе с путями мы так же используем строки. Есть командлет, который позволяет соединять части путей:
$directory = 'System32'
Join-Path -Path 'C:\Windows' -ChildPath $directory
Плюс этой команды в том, что он будет работать с любыми видами слэшей преобразовывая их в корректный формат:
Поиск и замена
Основной способ замены значений в строках - это использование параметра '-replace':
$job = 'Зовите меня Димон'
$job -replace 'Димон','Вован'
Если вы используете какие-то шаблоны для конфигурации сервисов хороший способ автоматизировать этот процесс - использовать явные идентификаторы, например "#IPADDRESS#". При надобности вы сможете найти это значение в тексте и заменить его:
$job = '
ipaddr: #IPADRESS#
DNS1: #DNS1#
'
$job -replace '#IPADRESS#','192.168.3.1' -replace '#DNS1#','8.8.8.8'
Еще один из способов такой подстановки - использование хэш таблиц (массив из ключей и значений). Такой способ подойдет, если вы используете множество идентификаторов. Мы объявляем хэш таблицу с нужными значениями, а через цикл проходим и применяем их к тексту:
$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
}
...
Подписывайтесь на наш Telegram канал
Теги: #powershell