Сравнить и обновить Json Массивы - PullRequest
1 голос
/ 02 марта 2020

У меня есть два набора файла json: Параметры1. json и Параметры2. json, как показано ниже:

Параметры1. json

{
    "TypeofService":"CITService",
    "ServiceName":"abc",
    "SCNNAME":"abc_V1.scn",
    "ScheduleInterval":"Daily",
    "ScheduleDay":"MON,TUE,WED,THU,FRI,SAT",
    "ScheduleTime":"08:30",
    "Folder_structure": "Success\\test1,Success\\test2",
    "CIT_Properties":  [
                           {
                               "isPassword":  false,
                               "Property":  "host1",
                               "Value":  "xyz"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "Port1",
                               "Value":  "8081"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "user1",
                               "Value":  "testuser"
                           },
                           {
                               "isPassword":  true,
                               "Property":  "password1",
                               "Value":  "12345"
                           }
                       ]
}

Параметры2. json (файл должен быть обновлен)

{
    "TypeofService":"CITService",
    "ServiceName":"abc",
    "SCNNAME":"abc_V2.scn",
    "ScheduleInterval":"Daily",
    "ScheduleDay":"MON,TUE,WED,THU,FRI,SAT",
    "ScheduleTime":"08:30",
    "Folder_structure": "Success\\test1,Success\\test2",
    "CIT_Properties":  [
                           {
                               "isPassword":  false,
                               "Property":  "host1",
                               "Value":  "xyz"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "port1",
                               "Value":  "8080"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "user1",
                               "Value":  "generic"
                           },
                           {
                               "isPassword":  true,
                               "Property":  "password1",
                               "Value":  "56789"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "host2",
                               "Value":  "xyz2"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "port2",
                               "Value":  "8080"
                           },
                           {
                               "isPassword":  false,
                               "Property":  "user2",
                               "Value":  "user2"
                           },
                           {
                               "isPassword":  true,
                               "Property":  "password2",
                               "Value":  "1234567890"
                           }
                       ]
}

Я пытаюсь добиться того, чтобы в случае совпадения «Property» в CIT_Properties в обоих файлах соответствовало значение CIT_properties.value из параметров1. json должно быть обновлено в параметрах 2. json.

т.е. если вы видите выше: порт1, пользователь1 и пароль1 являются общими в обоих файлах. Я хотел бы, чтобы значения (8080, generi c, 56789 в параметрах 2. json) были заменены на (8081, testuser, 12345).

То, что я сделал до сих пор, приведено ниже:

$json1 = (Get-Content "C:\Users\parameters1.json" -Raw) | Out-String | ConvertFrom-Json
$json2=(Get-Content "C:\Users\parameters2.json" -Raw) | Out-String | ConvertFrom-Json

for ($a = 0; $a -lt $json2.PsObject.properties.value.Property.length; $a++)
{
    for ($b = 0; $b -lt $json1.PsObject.properties.value.Property.length; $b++)
    {
        if ($json2.PsObject.properties.value.Property[$a] -eq $json1.PsObject.properties.value.Property[$b])
    {
            $json2.PsObject.properties.value.Value[$a]=  $json1.PsObject.properties.value.Value[$b]
        }
    }
}

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

Ответы [ 2 ]

1 голос
/ 02 марта 2020

Где-объект здесь твой друг. Если вы проведете l oop через меньший массив в файле 1, это будет более эффективным. Нет необходимости иметь вложенный l oop, поскольку Where Object должен работать быстрее. Это было протестировано в Powershell Core, но должно работать во всех версиях. Вы можете использовать Set-Content для обновления файла json или создания нового файла из переменной $ j2.

$j1 = Get-Content ./parameters1.json -Raw | ConvertFrom-Json
$j2 = Get-Content ./parameters2.json -Raw | ConvertFrom-Json

foreach ($Obj in $j1.CIT_Properties)
{
    ($j2.CIT_Properties | where {$_.Property -eq $Obj.Property}).Value = $Obj.Value
}

РЕДАКТИРОВАТЬ: Добавлен пример для ответа на комментарий. Этот ответ предполагает, что если script_properties существует в j1, он также существует в j2, я могу расширить ответ, если вы обновите json в своем вопросе.

, существующий в j2.

$j1 = Get-Content ./J1.json -Raw | ConvertFrom-Json
$j2 = Get-Content ./J2.json -Raw | ConvertFrom-Json

foreach ($Obj in $j1.CIT_Properties)
{
    ($j2.CIT_Properties | where {$_.Property -eq $Obj.Property}).Value = $Obj.Value
}

if ($j1.script_properties)
{
    if($j2.script_properties)
    {          
        foreach ($Obj in $j1.CIT_Properties)
        {
            ($j2.script_properties | where {$_.Property -eq $Obj.Property}).Value = $Obj.Value
        }
    }
    else 
    {
        $j2 | Add-Member -MemberType NoteProperty -Name script_properties -Value $j1.script_properties
    }
}

РЕДАКТИРОВАТЬ: Я думаю, что это то, что вы ищете. Я добавил условие, чтобы проверить, содержит ли массив j2 $ obj

$j1 = Get-Content ./J1.json -Raw | ConvertFrom-Json
$j2 = Get-Content ./J2.json -Raw | ConvertFrom-Json

foreach ($Obj in $j1.CIT_Properties)
{
    if ($j2.CIT_Properties -contains $obj)
    {
        ($j2.CIT_Properties | where {$_.Property -eq $Obj.Property}).Value = $Obj.Value
    }
}

if ($j1.script_properties)
{
    if($j2.script_properties)
    {          
        foreach ($Obj in $j1.CIT_Properties)
        {
            if ($j2.script_Properties -contains $obj)
            {
                ($j2.script_properties | where {$_.Property -eq $Obj.Property}).Value = $Obj.Value
            }
        }
    }
    else 
    {
        $j2 | Add-Member -MemberType NoteProperty -Name script_properties -Value $j1.script_properties
    }
}
1 голос
/ 02 марта 2020

Редактировать: просто используйте @ Дейв ответ

Это не супер элегантно и, возможно, немного медленнее, если ваши наборы данных большие.

Но что усложняет то, что ваши $json[x].CIT_Properties на самом деле являются массивами дочерних объектов PSCustomobjects. Вы можете увидеть это, выполнив $json1.Cit_properties.gettype(), который показывает, что это массив.

Так что все, что я мог подумать, это перебрать оба набора CIT_Properties и обновить атрибут value, где значения property то же самое

ForEach ($o in $json1.CIT_Properties) {
    ForEach ($t in $json2.CIT_Properties) {
     if ($t.Property -eq $o.Property) {
            $t.Value = $o.Value
        }
    }
}

(кстати, я просто назвал переменные l oop $o для «одного» и $t для «двух», чтобы было кристально ясно, какой json источник вас » переиндексация)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...