Windows PowerShell данные, которые инструкции извлекают, передают в другие инструкции и выводят на консоль, должны соответствовать типам данных Microsoft .NET Framework. В большинстве случаев PowerShell автоматически назначает и преобразует данные в их правильные типы. Но иногда полезно контролировать этот процесс, чтобы строить инструкции, более эффективно использующие доступные данные. Рассмотрим, как можно работать с несколькими типами данных и при необходимости приводить и преобразовывать данные к специфическим типам данных.

Действия со строками

Администраторы часто работают с данными в форме строк. В PowerShell это простой процесс. Так, в следующем примере строка «cat» назначается переменной $a, затем отображается результат, то есть cat:

$a = "cat"; $a

Поскольку строка назначается переменной $a, PowerShell автоматически приводит $a к типу System.String. Можно использовать метод GetType и его свойство FullName, чтобы определить тип данных переменной. Например, команда

a.GetType ().FullName

возвращает результат System.String. Чтобы объединить строки, используется оператор «плюс» (+). Например, следующий программный код добавляет строку " & dog " (вместе с пробелами) к переменной $a, а затем отображает результат, то есть cat & dog:

$a = $a + " & dog "; $a

В строку можно добавить числовое значение. При этом число автоматически преобразуется в строку. Например, следующий программный код добавляет 10 к переменной $a, а затем выводит на экран результат, cat & dog 10:

$a = $a + 10; $a

Если проверить тип данных, то это будет String.

Действия с числами

Работать с числовыми данными в PowerShell так же просто, как со строковыми. Числовые значения назначаются как строковые, единственное различие — числовые значения не заключаются в кавычки. Если указано числовое значение, PowerShell автоматически присваивает значению один из четырех типов данных (если не выполняется конкатенация числового значения в строку, как в предыдущем примере):

  • «System.Int32, 32-разрядное целое (псевдоним [int]).
  • System.Int64, 64-разрядное целое (псевдоним [long]).
  • System.Double, 8-байтное десятичное число с плавающей запятой (псевдоним [double]).
  • System.Decimal, 12-байтное десятичное число (псевдоним [decimal]). Точность Decimal выше, чем Double.

Следующие инструкции демонстрируют, как PowerShell назначает типы данных числовым значениям:

$a = 1234; $a
$a.GetType ().FullName
$a = 12345678910; $a
$a.GetType ().FullName
$a = 1234.5678; $a
$a.GetType ().FullName
$a = 1234.5678 d; $a
$a.GetType ().FullName

Как показано на экране 1, PowerShell назначает тип данных первым трем переменным в соответствии с этим значением.

Экран 1. Назначение типов данных числовым данным

Однако, чтобы назначить тип Decimal, необходимо прямо указать символ d после числа; в противном случае PowerShell обрабатывает значение как тип Double. Для соединения числовых значений можно использовать знак «плюс». При этом числовые значения складываются, а не сцепляются, как строковые. Например, следующие инструкции назначают значение 1234 переменной $a, а затем добавляют 1,5678 к $a:

$a = 1234; $a
$a.GetType ().FullName
$a = $a + 1.5678; $a
$a.GetType ().FullName

Как показано на экране 2, PowerShell складывает два значения и автоматически преобразует тип данных переменной из Int32 в Double.

Экран 2. Сложение двух числовых величин с разными типами данных

Если попытаться сложить строку, которая не является числом, с числовым значением, будет выдано сообщение об ошибке. PowerShell не может преобразовывать нечисловые строковые значения в числа. Например, можно прибавить строку «4» к числовому значению, но нельзя прибавить «four».

Действия с массивами

Массивы представляют собой коллекции типа System.Object []. Символы [] после типа данных показывают, что это массив со многими значениями. PowerShell автоматически назначает массивам тип Object []. Например,

$a = "a","b","c"; $a

создает массив с тремя строковыми переменными, а затем возвращает результаты

a
b
c

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

$a [0]

Эта инструкция возвращает результат a. Если нужно обратиться к более чем одному значению, просто укажите соответствующее число инструкций. Например, инструкции

$a [1]; $a [2]

возвращают результаты

b
c

Добавить элемент в массив можно с помощью оператора «плюс». Например, программный код

$a = $a + "d"; $a

добавляет d к массиву $a, а затем отображает результаты

a
b
c
d

Когда элемент d добавляется к массиву, PowerShell назначает ему следующий по порядку индекс (3). Числовые значения в массив ввести так же просто, как и строковые значения. Например, команда

$a = 1,2,3; $a

возвращает результаты

1
2
3

И вновь PowerShell назначает массиву тип Object []. В массив можно ввести числовое значение любого типа. В следующем примере назначается целочисленное значение (1) и два значения decimal (2.2 и 3.33) массиву $a:

$a = 1,2.2,3.33; $a

В действительности в массив можно ввести значение любого типа. Например, следующий программный код формирует массив, в который входит числовое значение (10), строковое значение («cat») и значение date-time (текущие время и дата, полученные с помощью команды Get-Date):

$a = 10, "cat", (Get-Date); $a
$a.GetType ().FullName

Как показано на экране 3, тип массива — Object [].

Экран 3. Объединение величин с разными типами данных в массив

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

$a [0].GetType ().FullName
$a [1].GetType ().FullName
$a [2].GetType ().FullName

В каждой инструкции применяется индекс для идентификации элемента, а затем GetType, чтобы извлечь тип элемента. Результаты показаны на экране 3. Чтобы изменить значение в массиве, нужно указать индекс элемента и назначить новое значение, например:

$a [2] = "dog"; $a
$a [2].GetType ().FullName

PowerShell заменяет значение и назначает правильный тип, как показано на экране 3.

Действия с хеш-таблицами

Хеш-таблицы — коллекции, которые принимают тип данных System.Collections.Hashtable. Основное различие между хеш-таблицами и массивами заключается в том, что для идентификации элементов в хеш-таблицах используются именованные ключи вместо индексов. Например, в следующем примере назначаются три ключа и их значения к хеш-таблице $a, а затем отображается содержимое таблицы и тип данных:

$a = @{b="bird"; c="cat"; d="dog"}
$a
$a.GetType ().FullName

Как видно из первой строки, хеш-таблица строится с использованием символа @, за которым следуют фигурные скобки, заключающие коллекцию пар ключ/значение. Первая пара ключ/значение — b/bird, как показано на экране 4.

Экран 4. Создание хеш-таблицы и восстановление ее ключей и значений

Можно получить список ключей хеш-таблицы с использованием свойства Keys, Например, инструкция

$a.Keys | sort

получает ключи хеш-таблицы $a, а затем использует команду Sort-Object (на которую указывает псевдоним sort) для сортировки ключей в алфавитном порядке. Аналогично можно использовать свойство Values для извлечения значений хеш-таблицы, как показывает инструкция

$a.Values | sort

Можно также извлечь отдельное значение, ссылаясь на ключ, как в инструкции

$a.b

На экране 4 показаны результаты трех последних инструкций. Чтобы добавить пару ключ/значение в хеш-таблицу, можно сослаться на новый ключ как на существующий, а затем ввести значение нового ключа, как в следующем примере:

$a = @{b="bird"; c="cat"; d="dog"}
$a.e = "elephant"; $a

Как показано на экране 5, добавляется пара ключ/значение e/elephant.

Экран 5. Добавление пары ключ/значение в хеш-таблицу

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

$a = @{b="bird"; c="cat"; d="dog"}; $a
$a.d = "dingo"; $a

В этом примере пара d/dog заменяется на d/dingo. Удалить пару ключ/значение можно с помощью метода Remove. Например, удаление пары d/dingo:

$a.remove ("d"); $a

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

Иногда полезно управлять типом данных, назначаемым скалярному (единственному) значению. Например, предположим, что значение 10 обрабатывается как числовое значение, а не строка. С помощью следующего программного кода можно создать переменную, которая содержит значение типа Double, хотя начальное значение — строка:

$a = [double] "10"
$a.GetType ().FullName

Обратите внимание, что тип Double указывается перед значением. Как показано на экране 6, того же результата можно достичь с помощью программного кода

[double] $b = "10"
$a.GetType ().FullName

Однако между двумя подходами есть различие. В первом случае значение просто заменяется на тип Double. При втором подходе выполняется строгий контроль типа переменной, то есть этой переменной можно назначать только значения того же типа данных. Проверить различие можно, попытавшись назначить строковое значение переменным $a и $b.

$a = "ten"; $a
$b = "ten"

Как показано на экране 6, можно назначить строку переменной $a, но не $b.

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

$c = [double []] ("1","2","3")
$c.GetType ().FullName

назначает тип Double [] массиву $c вместо выбираемого по умолчанию типа Object []. Символы [] означают, что это по-прежнему массив со многими значениями. Как показано на экране 7, следующий фрагмент программного кода приносит те же результаты:

[double []] $d = ("1","2","3")
$d.GetType ().FullName

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

$c [2] = "ten"
$d [2] = "ten"

ничего не получится (см. экран 7). Иногда требуется преобразовать тип данных существующей переменной. Например, преобразовать переменную date-time в строковую переменную можно с помощью программного кода

$e = Get-Date
$e.GetType ().FullName
$e = [string] $e
$e.GetType ().FullName

В этом фрагменте переменная $e первоначально содержит значение, возвращаемое командой Get-Date. Затем переменная преобразуется в тип String и задается другое значение переменной. Как показано на экране 8, PowerShell изменяет переменную на тип String.

Экран 8. Преобразование типов данных для скалярных значений и массивов

Аналогичный подход возможен для массива. В следующем примере создается массив типа Double [], массив преобразуется в тип String [] и значения вновь присваиваются массиву:

$f = [double []] («1»,»2»,»3»)
$f.GetType ().FullName
$f = [string []] $f
$f.GetType ().FullName

Как показано на экране 8, теперь тип данных переменной — String []. Даже если элементы массива принадлежат различным типам данных, можно преобразовать их все к одному типу с помощью следующего программного кода:

$g = 10, "ten", (Get-Date)
$g = [string []] $g

При преобразовании типа данных массива к String [] PowerShell преобразует все элементы в строковые значения.

Положитесь на PowerShell или на себя

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

Роберт Шелдон (contact@rhsheldon.com) — технический консультант и автор книг по технологиям Microsoft Windows и базам данных


Экран 6. Применение типа данных к скалярным величинам

Экран 7. Применение типа данных к массивам