Powershell Ссылка на объект JSON напрямую без итерации - PullRequest
0 голосов
/ 22 октября 2018

Новое в изучении PowerShell здесь, действительно открытое для любого решения, если оно содержится в данном скрипте

Действительно трудно найти что-либо в документации по этому поводу, что, возможно, означает, что ничего нет?

PSVersion 5.1

Версия сборки: 10.0.17134

Конкретный стандарт JSON или настройка файла не известны, но мы можем использовать это для примера:

{
  "foo" : ["foo1", "foo2", "foo3"],
  "bar" : {
     "bar-foo" : 20,
     "bar-bar" : {
       "bar-bar-foo : "here"
     }
   }
}

Я хотел бы просто перейти непосредственно к JSON KVP, так как я буду знать это свойство заранее, и это полный вложенный путь.

Например, входной аргумент будет:

.\ScriptName -JsonProp ["bar"]["bar-bar"]["bar-bar-foo"]

Мой сценарий в настоящее время использует ConvertTo-Json, и источником является любой данный файл .json, но если есть более простой или более удобный способ явной навигации по объекту json, я всеуши.

Цель состоит в том, чтобы изменить значение этого свойства и записать его в файл

$json = Get-Content -Raw -Path $path | ConvertFrom-Json

$json.$JsonProp = "there"

Насколько я могу судить, объект Json должен использовать точечную запись, но япробовал что-то со строками снет решения, разделив параметр, например:

.\ScriptName -JsonProp bar.bar-bar.bar-bar-foo

$json.$JsonProp = "there"

Пока я нахожусь в теме, если у вас есть какие-либо рекомендации для литературы по PowerShell, пожалуйста, дайте мне знать.

Ответы [ 3 ]

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

если есть более простой или более дружественный способ явной навигации по объекту json, я весь в ушах

Да, есть много ... Вот пример использования jq Анализатор командной строки JSON

При условии, что в вашем образце JSON для изменения значения here на there вы просто сделаете:

jq '.bar."bar-bar"."bar-bar-foo" |= "there"' file
{
  "foo": [
    "foo1",
    "foo2",
    "foo3"
  ],
  "bar": {
    "bar-foo": 20,
    "bar-bar": {
      "bar-bar-foo": "there"
    }
  }
}

In jq оператор присваивания |=.

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

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

Вот один из способов:

$newValue = "there"
Invoke-Expression ('$json.' + $JsonProp + ' = $newValue')

Вы должны будете включить в аргумент кавычки:

.\ScriptName -JsonProp "bar.'bar-bar'.'bar-bar-foo'"

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

# (Note: This is just a quick example. Not pretty or complete, but does the job.)
if ($JsonProp -notmatch '^([a-zA-Z0-9_\-]+|''[a-zA-Z0-9_\-"]+''|"[a-zA-Z0-9_\-'']+")(\.([a-zA-Z0-9_\-]+|''[a-zA-Z0-9_\-"]+''|"[a-zA-Z0-9_\-'']+"))*$') {
    throw "Invalid json property."
}
0 голосов
/ 22 октября 2018

Любой идентифицированный в вашем объекте JSON, который содержит не-буквенный символ, должен быть заключен в кавычки:

$rawJson = @"
{
  "foo": ["foo1", "foo2", "foo3"],
  "bar": {
     "bar-foo": 20,
     "bar-bar": {
       "bar-bar-foo" : "here"
     }
  }
}
"@

$json = ConvertFrom-Json -InputObject $rawJson

# Note the quotes!!
$json.bar."bar-bar"."bar-bar-foo" = "Hello thar!"

$json | ConvertTo-Json

Результат

{
    "foo":  [
                "foo1",
                "foo2",
                "foo3"
            ],
    "bar":  {
                "bar-foo":  20,
                "bar-bar":  {
                                "bar-bar-foo":  "Hello thar!"
                            }
            }
}

Использование "Dymanic" пути JSON

ВАЖНЫЙ ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: этот код опасен.Вы можете передать все виды в переменную $jsonPath, и она будет выполнена.Это похоже на SQL-инъекцию, и вам нужно быть очень осторожным.

Обязательный xkcd

$rawJson = @"
{
  "foo": ["foo1", "foo2", "foo3"],
  "bar": {
     "bar-foo": 20,
     "bar-bar": {
       "bar-bar-foo" : "here"
     }
  }
}
"@

$jsonPath = 'bar."bar-bar"."bar-bar-foo"'
$newValue = "Hello thar!"
$command = "`$json.$jsonPath = '$newValue'"

$json = ConvertFrom-Json -InputObject $rawJson

Invoke-Expression $command

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