Освоение строк PowerShell: конкатенация, разделение и многое другое

Строки в PowerShell, вероятно, являются наиболее используемым типом данных в PowerShell. Начиная от отображения сообщений, запросов ввода или отправки данных в файлы, почти невозможно написать сценарии без участия строк.

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

Понимание строк

Согласно определению .NET, строка – это последовательная коллекция символов, используемая для представления текста. В общем, пока есть последовательность символов, образующая текст, есть строка.

Определение строк системы в PowerShell

Строки определяются путем заключения серии символов в одинарные или двойные кавычки. Ниже приведены примеры строки.

PS> 'Hello PowerShell - Today is $(Get-Date)'PS> "Hello PowerShell - Today is $(Get-Date)"

На самом деле строки – это объекты System.String в .NET.

Как видно из приведенного выше примера, первая строка заключена в одинарные кавычки, а вторая – в двойные. Если вы задаетесь вопросом, единственное различие между ними заключается в том, что строки в двойных кавычках поддерживают расширение строк, в то время как одинарные кавычки представляют только буквальные строки.

Чтобы подтвердить концепцию одинарных кавычек против двойных, при вставке обеих строк из приведенного выше примера в PowerShell.

Снимок экрана ниже показывает, что строка в одинарных кавычках возвращает точно ту строку, которая была определена. В то время как строка в двойных кавычках возвращает строку с результатом выражения командлета Get-Date.

Single Quote vs. Double-Quote String Output

Показанный выше результат демонстрирует различие в том, когда следует использовать одинарные или двойные кавычки при определении строк.

Объект String

Как указано в предыдущем разделе, набор символов, образующих текст, называется строкой. Результирующее значение строки является объектом String. Объект String является объектом .NET, который имеет тип [System.String].

И поскольку System.String является объектом, у него есть свойства, к которым вы можете обратиться с помощью командлета Get-Member. Ниже мы вставляем переменную внутри строки с двойными кавычками.

PS> "Hello PowerShell - Today is $(Get-Date)" | Get-Member=

Снимок экрана ниже показывает TypeName и частичный список свойств объекта String.

String Object properties

Конкатенация строк в PowerShell

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

A typical example of using string concatenation in the real world is Active Directory user creation. Perhaps you’re creating a user creation script that takes the first name, last name, and department values from a list.

С использованием оператора конкатенации строк вы можете сформулировать стандартное соглашение об именах, отображаемых именах, именах пользователей и адресах электронной почты. Ниже приведен пример кода, который вы можете скопировать и вставить в вашу сессию PowerShell.

$domain = 'contoso.com'
$firstname = 'Jack'
$lastname = 'Ripper'
$department = 'Health'

Используя приведенные выше значения переменных, целью является получение следующих значений путем конкатенации строк.

  • Имя = имя фамилия
  • Отображаемое имя = имя фамилия (отдел)
  • SamAccountName = имя.фамилия
  • Адрес электронной почты = имя.фамилия@contoso.com

В следующих разделах будут созданы указанные выше значения с использованием различных методов конкатенации строк, доступных в PowerShell.

Давайте начнем!

Используя оператор конкатенации строк PowerShell

У каждого языка программирования есть свой собственный оператор конкатенации строк. Например, в Visual Basic это знак амперсанда (&). PowerShell также имеет свой метод конкатенации, который представлен знаком плюс (+).

С использованием оператора конкатенации строк вы можете объединить строки с помощью следующего кода.

## Имя
$firstname + ' ' + $lastname
## Отображаемое имя
$firstname + ' ' + $lastname + ' (' + $department + ')'
## SamAccountName
$firstname + '.' + $lastname
## Адрес электронной почты
$firstname + '.' + $lastname + '@' + $domain

Использование расширения строк PowerShell

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

# Использование расширения строк
## Имя
"$firstname $lastname"
## Отображаемое имя
"$firstname $lastname ($department)"
## Имя учетной записи Sam
"$firstname.$lastname"
## Адрес электронной почты
"$firstname.$lastname@$domain"

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

Using String Expansion

Использование оператора форматирования PowerShell

Оператор форматирования (-f) в основном используется для составного форматирования. Важно помнить, что при этом методе есть три части использования -f.

Обратитесь к третьей строке кода ниже. "{0} {1}" представляет формат и заполнители. Числа в фигурных скобках указывают индекс строки в коллекции, которую нужно отобразить на ее месте. Кавычки могут быть одинарными или двойными.

Коллекция строк ввода в этом примере представлена как $firstname,$lastname. Это означает, что индекс переменной $firstname равен 0, а $lastname равен 1.

Наконец, -f – это место между заполнителем и набором строк, представленных (-f).

## Имя
"{0} {1}" -f $firstname,$lastname
## Отображаемое имя
"{0} {1} ({2})" -f $firstname,$lastname,$department
## SamAccountName
"{0}.{1}" -f $firstname,$lastname
## Адрес электронной почты
"{0}.{1}@{2}" -f $firstname,$lastname,$domain

Код выше приведет к показанным ниже результатам.

Using the Format Operator

Использование оператора PowerShell -Join

Оператор -Join можно использовать для объединения строк в одну строку двумя способами.

Первый способ использования -Join – следовать за ним массивом строк, которые вы хотите объединить. Оператор -Join не предоставляет опции добавления разделителя. Все строки в массиве будут склеены вместе без чего-либо между ними.

-Join <String[]>

Второй способ использования оператора -Join – указать разделитель, который следует использовать. Массив строк будет объединен, но указанный символ-разделитель будет вставлен между каждой строкой.

<String[]> -Join <Delimiter>

Возвращаясь к цели объединения строк, приведенный ниже код демонстрирует, как использовать оператор -Join для объединения строк.

## Имя
$firstname, $lastname -join ' '
## Отображаемое имя
$firstname,$lastname,"($department)" -join ' '
## SamAccountName
-join ($firstname,'.',$lastname)
## Адрес электронной почты
-join ($firstname,'.',$lastname,'@',$domain)

Когда вы запускаете приведенный выше пример кода в PowerShell, вы ожидаете увидеть аналогичный вывод, как показано ниже.

Using the PowerShell Join Operator

.NET String.Format() Метод

Метод String.Format в .NET является аналогом оператора форматирования PowerShell PowerShell Format Operator. Он работает так же, как оператор форматирования, где необходимо указать формат и заполнители.

## Имя
[string]::Format("{0} {1}",$firstname,$lastname)
## Отображаемое имя
[string]::Format("{0} {1} ({2})",$firstname,$lastname,$department)
## SamAccountName
[string]::Format("{0}.{1}",$firstname,$lastname)
## Адрес электронной почты
[string]::Format("{0}.{1}@{2}",$firstname,$lastname,$domain)

На следующем снимке экрана показан Метод String.Format в действии.

The .NET String.Format Method

.NET String.Concat() Метод

Другой способ объединения строк – использовать Метод String.Concat в .NET. Метод String.Concat в .NET является аналогом оператора конкатенации строк PowerShell (+). Однако вместо использования знака + для объединения строк, вы можете добавить все строки внутри метода, как показано здесь – [string]::Concat(string1, string2...).

## Имя
[string]::Concat($firstname,' ',$lastname)
## Отображаемое имя
[string]::Concat($firstname,' ',$lastname,' (',$department,')')
## Имя учетной записи Sam
[string]::Concat($firstname,'.',$lastname)
## Адрес электронной почты
[string]::Concat($firstname,'.',$lastname,'@',$domain)

На скриншоте ниже показан результат вызова метода String.Concat .NET. Вы можете видеть, что PowerShell объединил string1, string2.

Using the .NET String.Concat Method

Метод .NET String.Join()

Метод String.Join .NET является аналогом оператора объединения PowerShell (-join) в .NET. Формат этого метода следующий: [string]::Join(<разделитель>,<строка1>,<строка2>,...).

Первый элемент в методе -Join всегда является разделителем. Затем следующие значения элементов – это строки, которые вы хотите объединить. Вот пример кода ниже. Помните, что первый элемент всегда является разделителем. Если вы не хотите добавлять разделитель, то можете указать это —> ''.

## Имя
[string]::Join(' ',$firstname,$lastname)
## Отображаемое имя
[string]::Join(' ',$firstname,$lastname,"($department)")
## Имя учетной записи Sam
[string]::Join('',$firstname,'.',$lastname)
## Адрес электронной почты
[string]::Join('',$firstname,'.',$lastname,'@',$domain)
The .NET String.Join Method

Разделение строк PowerShell

Вы видели несколько различных методов конкатенации строк в предыдущем разделе. В этом разделе вы узнаете о различных способах использования PowerShell для разделения строк. Разделение строк – это обратное действие конкатенации.

Вы можете разбить строки в PowerShell двумя разными способами – с помощью функции/метода split() или оператора split.

Разделение строк с помощью метода Split()

Если вы ищете простой способ разделить строку и создать массив, обратите внимание на метод split(). Метод split() доступен для каждого объекта строки и способен разделить строку на массив на основе указанного символа без использования регулярных выражений.

Например, если у вас есть строка зеленый|яйца|и|ветчина, и вы хотите создать массив @('зеленый','яйца','и','ветчина'), вы можете разделить эту строку по символу вертикальной черты (|), как показано в следующем фрагменте кода.

$string = 'green|eggs|and|ham'
$string.split('|')

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

Метод split() – это простой способ разделить строки, но он ограничен. Метод split() не позволяет разделять строки с использованием регулярных выражений. Если вам нужны более продвинутые возможности для разделения строки, вам придется изучить оператор split.

Оператор -split

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

Ниже приведен синтаксис оператора -Split для вашего справочного материала. Обратите внимание на разницу между унарным и бинарным разделением.

# Одиночное разделение
-Split <String>
-Split (<String[]>)

# Двоичное разделение
<String> -Split <Delimiter>[,<Max-substrings>[,"<Options>"]]
<String> -Split {<ScriptBlock>} [,<Max-substrings>]

В этом примере переменная $string содержит значение одной строки. Затем с помощью оператора -Split строка разбивается на массив строк PowerShell. Разделенная строка сохраняется в переменной $split.

## Разделение строк на подстроки
# Присвоить строковое значение переменной $string
$string = 'This sentence will be split between whitespaces'
# Разделить значение $string и сохранить результат в переменной $split
$split = -split $string
# Получить количество полученных подстрок
$split.Count
# Показать полученные подстроки
$split

Как видно из результатов выше, изначально одна строка была разбита на 7 подстрок. Это демонстрирует, как PowerShell разбивает строку на массив.

Символьный разделитель

В предыдущем примере оператор -Split разбил одиночный объект строки на несколько подстрок даже без указания разделителя; это потому, что разделитель по умолчанию для оператора -Split – это пробел. Однако разделителями также могут быть символы, строки, шаблоны или блоки сценариев.

В этом примере в качестве разделителя используется точка с запятой ;.

## Разделение строк на подстроки с разделителем
# Присвойте строковое значение переменной $string
$string = 'This;sentence;will;be;split;between;semicolons'
# Разделите значение $string и сохраните результат в переменной $split
$split = $string -split ";"
# Получите количество полученных подстрок
$split.Count
# Покажите полученные подстроки
$split

Когда вы тестируете указанный выше код в PowerShell, вы получите следующий результат.

Splitting a String into Substrings with Character Delimiter

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

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

$split = $string -split "(;)"
$split.Count
$split

После модификации разделителя, как показано выше, его выполнение приведет к следующему результату.

Splitting a string on semicolon

Результат выше показывает, что разделительные символы не опускаются и учитываются в полученных подстроках.

Разделитель строк

Строки также могут быть разделены другой строкой в качестве разделителя. В этом примере в качестве разделителя используется строка “day”.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split "day"

Разделитель блока сценария

A scriptBlock as the delimiter enables the -Split operator to perform custom or complex splitting of strings.

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

Пример ниже использует выражение {$PSItem -eq 'e' -or $PSItem -eq 'y'}, что означает, что строка будет разделена, если входной символ 'e' или 'a'.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split {$PSItem -eq 'e' -or $PSItem -eq 'y'}

И когда вы запускаете эту команду выше, выводом будут подстроки, разделенные символами-разделителями, указанными в выражении в блоке сценария.

Splitting a String into Substrings with a Script Block Delimiter

В следующем примере сценария делается немного больше. На этот раз выражение оценивает, что:

  • Входной символ проходит как целое число; и
  • Что его значение больше 1

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

$daysOfTheWeek= 'monday1tuesday2wednesday3thursday1friday4saturday8sunday'
$daysOfTheWeek -split {
    try {
        [int]$PSItem -gt 1
    }
    catch {
        #НИЧЕГО НЕ ДЕЛАТЬ
    }
}

После выполнения приведенного выше кода ожидается, что строка будет разделена там, где значение символа может быть приведено к целому числу со значением больше 1. Ниже показан ожидаемый вывод.

Splitting a String into Substrings with a Script Block Delimiter

Разделитель RegEx

По умолчанию оператор -Split использует сопоставление с RegEx указанным разделителем. Это означает, что вы также можете использовать RegEx в качестве разделителей для разделения строк.

В этом следующем примере строка содержит буквенно-цифровые символы и не буквенно-цифровые символы. Цель состоит в том, чтобы разделить строку с помощью любых не буквенно-цифровых символов. В регулярных выражениях не буквенно-цифровые символы представлены как \W, а буквенно-цифровые символы, которые совпадают с этими символами – как \w.

$daysOfTheWeek= 'monday=tuesday*wednesday^thursday#friday!saturday(sunday'
$daysOfTheWeek -split "\W"

Ограничение подстрок

Также возможно остановить оператор -Split от разделения строки на ряд подстрок. Параметр, который можно использовать для ограничения результата разделения на подстроки – это параметр <Максимальное-количество-подстрок>.

Когда вы обращаетесь к синтаксису -Split, параметр <Максимальное-количество-подстрок> – это параметр, который непосредственно следует за параметром <Разделитель>. Синтаксис показан снова ниже для справки.

<String> -Split <Delimiter>[,<Max-substrings>[,"<Options>"]]

Следуя указанному выше синтаксису, приведенный ниже пример кода изменен для ограничения количества разделенных подстрок до 3.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split ",",3

И, запуск кода выше приводит к следующему выводу. Как видно из вывода ниже, строка была разделена только на три подстроки. Остальные разделители были пропущены.

Limiting the Number of Substrings starting from the first 3 matched delimiters

Теперь, если вы хотите ограничить подстроки, но в обратном порядке, вы можете изменить значение параметра <Максимальное-количество-подстрок> на отрицательное значение. В этом следующем примере <Максимальное-количество-подстрок> изменено на -3.

$daysOfTheWeek= 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -split ",",-3

И в результате измененного кода выше, строка была разделена, начиная с последних трех совпавших разделителей.

Limiting the Number of Substrings starting from the last 3 matched delimiters

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

В этом разделе вы узнаете о двух методах, которые можно использовать для поиска и замены строки в PowerShell. Метод Replace() и оператор -Replace.

Метод Replace()

Объект строки также имеет встроенный метод, который может помочь выполнить операции поиска и замены – метод replace(). Метод replace() может принимать максимум четыре перегрузки.

Допустимый набор перегрузок для метода replace() перечислен ниже.

<String>.Replace(<original>, <substitute>[, <ignoreCase>][, <culture>])

Единственные обязательные перегрузки – <original> и <substitute>. <ignoreCase> и <culture> являются необязательными.

В приведенном ниже примере кода будет выполнен поиск всех вхождений символа запятой (,) и заменены на символ точки с запятой (;).

$daysOfTheWeek = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek.Replace(',',';')

Помимо замены одиночного символа, вы также можете использовать метод replace() для поиска и замены строк. Приведенный ниже пример кода заменяет слово “день” на “ночь”.

$daysOfTheWeek = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek.Replace('day','NIGHT')
Replacing a matched string using the replace() method

Оператор -Replace

Синтаксис оператора замены показан ниже.

<string> -replace <original>, <substitute>

Используя приведенный выше синтаксис, приведенный ниже пример кода заменяет слово “день” на “Ночь” с помощью оператора -replace.

$daysOfTheWeek = 'monday,tuesday,wednesday,thursday,friday,saturday,sunday'
$daysOfTheWeek -replace 'day','NIGHT'
Replacing a matched character with the -replace operator

Этот следующий пример использует сопоставление регулярных выражений для замены строк с помощью оператора -replace. Вот код, который ищет ссылочную строку для строки, соответствующей (#.) и заменяет их на ничего.

$daysOfTheWeek = @'
1. Line 1
2. Line 2
3. Line 3
4. Line 4
5. Line 5
'@
$daysOfTheWeek -replace "\d.\s",""
Replacing a RegEx match using -replace

Извлечение строк из строк

Объект строки имеет метод, называемый SubString(). Метод SubString() используется для извлечения строк из строк в определенных местах. Синтаксис метода SubString() показан ниже.

<String>.SubString(<startIndex>[,<length>])

startIndex – это позиционный индекс, с которого метод SubString() начнет поиск. Параметр length указывает количество символов, которые будут возвращены, начиная с startIndex. Параметр length необязателен, и если его не использовать, метод SubString() вернет все символы.

Извлечение подстроки из начальной позиции и фиксированной длины

Приведенный ниже пример кода извлекает часть строки $guid начиная с индекса 9 и возвращает ровно 5 символов, которые следуют за ними.

$guid = 'e957d74d-fa16-44bc-9d72-4bea54952d8a'
$guid.SubString(9,5)

Извлечение подстроки из динамической начальной позиции

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

Ниже приведен код, который выполняет следующее:

  • Получает длину строки.
  • Получает индекс среднего элемента, разделив длину на 2.
  • Использует средний индекс в качестве начального индекса подстроки.
$guid = 'e957d74d-fa16-44bc-9d72-4bea54952d8a'
$guid.SubString([int]($guid.Length/2))

Поскольку значение length не было указано, метод Substring() вернул все символы, начиная с начального индекса.

Extracting a Substring from a Dynamic Starting Position

Сравнение строк в PowerShell

Вы также можете использовать PowerShell для сравнения строк, используя встроенные методы объекта строк, такие как методы CompareTo(), Equals() и Contains(). Или с помощью операторов сравнения PowerShell  .

Использование метода CompareTo()

Метод CompareTo() возвращает значение 0, если две строки имеют одинаковое значение. Например, приведенный ниже код сравнивает два объекта строк.

$string1 = "This is a string"
$string2 = "This is a string"
$string1.CompareTo($string2)

И поскольку значения одинаковы, результат должен быть 0, как показано ниже.

Using CompareTo() method to compare strings

Использование метода Equals() и -eq

Метод Equals() и оператор -eq могут быть использованы для проверки равенства значений двух строк.

Приведенный ниже пример использует метод Equals() для сравнения значений $string1 и $string2.

$string1 = "This is a string"
$string2 = "This is not the same string"
$string1.Equals($string2)

Код выше должен вернуть False, потому что значения $string1 и $string2 не равны друг другу.

Comparing strings with the Equals() method

Следующий пример кода использует оператор -eq для сравнения значений $string1 и $string2.

$string1 = "This is a string"
$string2 = "This is not the same string"
$string1 -eq $string2

Как видно из вывода ниже, результат при использовании -eq и метода Equal() одинаковый.

Comparing strings with the -eq operator

Используя метод Contains()

В этом примере две строки сравниваются путем проверки, содержит ли строка PowerShell подстроку другой строки.

Код ниже показывает, что значения $string1 и $string2 не равны. Однако значение $string2 является подстрокой $string1.

$string1 = "This is a string 1"
$string2 = "This is a string"
$string1.Contains($string2)

Результат кода выше должен быть True, как показано ниже.

Comparing strings using the Contains() method

Дополнительное чтение

Source:
https://adamtheautomator.com/powershell-strings/