Тут обнаружился один интересный командлет – ConvertFrom-StringData, который позволяет преобразовывать строку в хэш-таблицы. Скажем, есть файл вида:
ключ1 = значение1
ключ2 = значение2
ключ3 = значение3
ключ4 = значение4
при этом иногда очень хочется работать с этими строками как с объектами. Т.е. при указании объекта и его ключа, например, $a.key1 получить его значение. Как это делается в хэш-таблицах. Вот пример:
[vPodans] $a = @{"key1"="value1";"key2"="value2"}
[vPodans] $a
Name Value
---- -----
key2 value2
key1 value1
[vPodans] $a.key1
value1
[vPodans] $a.key2
value2
[vPodans]
здесь я создал простую хэш-таблицу. Но если у нас есть файл общего вида, ключ = значение, то его можно легко привести в вид хэш-таблиц:
[vPodans] $a = "key1 = value1"
[vPodans] $a
key1 = value1
[vPodans] $a.GetType().FullName
System.String
[vPodans] $b = ConvertFrom-StringData -StringData $a
[vPodans] $b
Name Value
---- -----
key1 value1
[vPodans] $b.GetType().FullName
System.Collections.Hashtable
[vPodans] $b.key1
value1
[vPodans]
сперва я создал строку, которая состоит из пары ключ = значение, в чём мы можем убедиться в типе данных. Вторым этапом я сконвертировал эту строку в хэш-таблицу. Однако, следует учесть, что такое возможно только для строки, но не массива строк. Вот так легко попасть в засаду:
[vPodans] $a = gc keys.txt
[vPodans] $a
key1 = value1
key2 = value2
key3 = value3
key4 = value4
[vPodans] $a[0]
key1 = value1
[vPodans] ConvertFrom-StringData -StringData $a
ConvertFrom-StringData : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'StringData
'. Specified method is not supported.
At line:1 char:35
+ ConvertFrom-StringData -StringData <<<< $a
+ CategoryInfo : InvalidArgument: (:) [ConvertFrom-StringData], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand
[vPodans]
командлет Get-Content (или его алиас GC, не путать с глобальным каталогом) читает файл построчно в виде массива. Следовательно каждая строка является отдельным элементом массива. Как быть в такой ситуации? На первый взгляд может показаться, что можно Get-Content разобрать через Foreach-Object и уже отдельные элементы массива подавать конвертеру в качестве строк. Смотрим:
[vPodans] $a = gc keys.txt | %{ConvertFrom-StringData -StringData $_}
[vPodans] $a
Name Value
---- -----
key1 value1
key2 value2
key3 value3
key4 value4
[vPodans] $a.key1
[vPodans] $a.GetType().FullName
System.Object[]
[vPodans] $a[0].key1
value1
[vPodans]
Как видите, мы на выходе получили не одну хэш-таблицу, а массив одиночных хэш-таблиц и для доступа к его ключам и значениям нужно ещё указывать номер элемента в массиве. Чтобы решить данную проблему нужно каким-то образом прочитать файл не построчно, а в виде целой строки. Для чтения файла целиком можно воспользоваться методом ReadAllText класса File Class. Как видно из описания метода, он читает текст в единую строку. Давайте посмотрим, что у нас получится:
[vPodans] $a = [io.file]::ReadAllText("keys.txt")
[vPodans] $a
key1 = value1
key2 = value2
key3 = value3
key4 = value4
[vPodans] $a.GetType().FullName
System.String
[vPodans] $b = ConvertFrom-StringData -StringData $a
[vPodans] $b
Name Value
---- -----
key2 value2
key4 value4
key1 value1
key3 value3
[vPodans] $b.key1
value1
[vPodans] $b.key2
value2
[vPodans] $b.key3
value3
[vPodans] $b.key4
value4
[vPodans]
или просто в одну строчку:
ConvertFrom-StringData -StringData ([io.file]::ReadAllText("keys.txt"))
Вот так просто в стиле The PowerShell Way (в одну строчку) можно текстовые файлы сконвертировать в хэш-таблицы и работать с ними как с объектами, что есть удобно и полезно.