В 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 }
Ваш комментарий будет первым