Powershell анализирует файл свойств, содержащий двоеточия

Если у меня есть файл .properties, содержащий каталоги (содержащие двоеточия):

some_dir=f:\some\dir\etc
another_dir=d:\dir\some\bin

а затем используйте ConvertFrom-StringData для преобразования пар Key = Value из указанного файла свойств в хеш-таблицу:

$props_file = Get-Content "F:\dir\etc\props.properties"
$props = ConvertFrom-StringData ($props_file)
$the_dir = $props.'some_dir'
Write-Host $the_dir

Powershell выдает ошибку (не любит двоеточия):

ConvertFrom-StringData : Cannot convert 'System.Object[]' to the type 'System.String'    required by parameter 'StringData'. Specified method is not supported.
At line:3 char:32
+ $props = ConvertFrom-StringData <<<<  ($props_file)
+ CategoryInfo          : InvalidArgument: (:) [ConvertFrom-StringData],     ParameterBindingException
+ FullyQualifiedErrorId :     CannotConvertArgument,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand

Как это обойти? Я хотел бы иметь возможность просто ссылаться на каталоги, используя расширение. обозначение:

$props.'some_dir'

person ar.dll    schedule 10.06.2014    source источник


Ответы (3)


Двоеточие не имеет никакого отношения к полученной вами ошибке. И да, этого можно добиться с помощью ConvertFrom-StringData, но, как уже упоминалось, вы передаете ему массив вместо строки. Более того, вам нужны пути с двойными обратными косыми чертами в вашем файле, потому что одиночные обратные косые черты интерпретируются как escape-символы.

Вот как исправить ваш код:

# Reading file as a single string:
$sRawString = Get-Content "F:\dir\etc\props.properties" | Out-String

# The following line of code makes no sense at first glance 
# but it's only because the first '\\' is a regex pattern and the second isn't. )
$sStringToConvert = $sRawString -replace '\\', '\\'

# And now conversion works.
$htProperties = ConvertFrom-StringData $sStringToConvert

$the_dir = $htProperties.'some_dir'
Write-Host $the_dir
person Alexander Obersht    schedule 10.06.2014
comment
Вы получите ошибку Unrecognized escape sequence, только если в значении есть неэкранированная косая черта. Если ключ имеет косую черту, он игнорируется. Следовательно, описанный выше подход, к сожалению, непригоден, если в ваших клавишах тоже будут косые черты. - person Chris Oldwood; 05.05.2016

ConvertFrom-StringData ожидает строку, а вы передаете ей командлет массива Get-Content. Измените $props_file на:

$props_file = (Get-Content "F:\dir\etc\props.properties") | Out-String

и вы получите еще одну ошибку:

ConvertFrom-StringData : parsing "f:\some\dir\etc" - Unrecognized escape sequence \s.

Обойти это можно так:

$props_file = Get-Content "F:\dir\etc\props.properties"
$props = @{}
$props_file | % {
    $s = $_ -split "="
    $props.Add($s[0],$s[1])
}
$the_dir = $props.'some_dir'
Write-Host $the_dir

Результат:

f:\some\dir\etc
person Raf    schedule 10.06.2014

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

$props = @{}
GC "F:\dir\etc\props.properties" | %{$props.add($_.split('=')[0],$_.split('=')[1])}
person TheMadTechnician    schedule 10.06.2014