Найти и заменить вложенные значения JSON на Powershell - PullRequest
0 голосов
/ 13 октября 2018

У меня есть файл appsettings.json, который я хотел бы преобразовать с помощью сценария PowerShell в задачу PowerShell конвейера выпуска VSTS.(Кстати, я развертываю netstandard 2 Api для IIS).Структура JSON выглядит следующим образом:

{
    "Foo": {
        "BaseUrl": "http://foo.url.com",
        "UrlKey": "12345"
    },
    "Bar": {
        "BaseUrl": "http://bar.url.com"
    },
    "Blee": {
        "BaseUrl": "http://blee.url.com"
    }
}

Я хочу заменить BaseUrl и, если она существует, значения UrlKey в каждом разделе: Foo, Bar и Blee.(Foo: BaseUrl, Foo: UrlKey, Bar: BaseUrl и т. Д.)

Я использую следующую структуру JSON для хранения новых значений:

{ 
    "##{FooUrl}":"$(FooUrl)", 
    "##{FooUrlKey}":"$(FooUrlKey)",
    "##{BarUrl}":"$(BarUrl)",
    "##{BleeUrl}":"$(BleeUrl)"
}

Пока у меня естьследующий скрипт:

# Get file path
$filePath = "C:\mywebsite\appsettings.json"

# Parse JSON object from string
$jsonString = "$(MyReplacementVariablesJson)"
$jsonObject = ConvertFrom-Json $jsonString

# Convert JSON replacement variables object to HashTable
$hashTable = @{}
foreach ($property in $jsonObject.PSObject.Properties) {
    $hashTable[$property.Name] = $property.Value
}

# Here's where I need some help

# Perform variable replacements
foreach ($key in $hashTable.Keys) {
    $sourceFile = Get-Content $filePath
    $sourceFile -replace $key, $hashTable[$key] | Set-Content $filePath
    Write-Host 'Replaced key' $key 'with value' $hashTable[$key] 'in' $filePath
}

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

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

$json = (Get-Content -Path $filePath) | ConvertFrom-Json

    $json.Foo.BaseUrl = $newUrls["Foo"]
    $json.Bar.BaseUrl = $newUrls["Bar"]
    $json.Blee.BaseUrl = $newUrls["Blee"]

    $json.Foo.Key = $newKeys["Foo"]

$json | ConvertTo-Json | Set-Content $filePath

Надеюсь, это может помочь кому-то еще.

0 голосов
/ 14 октября 2018

Почему вы определяете значения замены в виде строки JSON?Это просто сделает вашу жизнь более несчастной.Если вы в любом случае определяете значения в своем скрипте, просто сразу определите их как хеш-таблицы:

$newUrls = @{
    'Foo'  = 'http://newfoo.example.com'
    'Bar'  = 'http://newbaz.example.com'
    'Blee' = 'http://newblee.example.com'
}

$newKeys = @{
    'Foo' = '67890'
}

Даже если вы хотите прочитать их из файла, вы можете сделать этот файл скриптом PowerShell, содержащим эти хеш-таблицы иточечный источник это.Или, по крайней мере, определите значения в виде списков key=value строк в текстовых файлах, которые легко можно превратить в хеш-таблицы:

$newUrls = Get-Content 'new_urls.txt' | Out-String | ConvertFrom-StringData
$newKeys = Get-Content 'new_keys.txt' | Out-String | ConvertFrom-StringData

Затем выполните итерации по свойствам верхнего уровня ваших входных данных JSON и заменитевложенные свойства с новыми значениями:

$json = Get-Content $filePath | Out-String | ConvertFrom-Json
foreach ($name in $json.PSObject.Properties) {
    $json.$name.BaseUrl = $newUrls[$name]
    if ($newKeys.ContainsKey($name)) {
        $json.$name.UrlKey = $newKeys[$name]
    }
}
$json | ConvertTo-Json | Set-Content $filePath

Обратите внимание, что если ваши фактические данные JSON имеют более 2 уровней иерархии, вам нужно будет указать ConvertTo-Json через параметр -Depth, сколько уровней предполагаетсядля преобразования.


Примечание: требуется передача Get-Content через Out-String, поскольку ConvertFrom-Json ожидает ввод JSON в виде одной строки, а использование Out-String делает код работающим со всемиВерсии PowerShell.Если у вас PowerShell v3 или новее, вы можете немного упростить код, заменив Get-Content | Out-String на Get-Content -Raw.

...