使用带点符号的变量编辑/访问Powershell对象

使用带点符号的变量编辑/访问Powershell对象,powershell,Powershell,我正在尝试编辑PowerShell中通过导入JSON文件创建的对象。然后我尝试使用点符号来访问或修改对象的属性 例如,下面是一个JSON示例和一个代码片段 { "menus": { "menu1": { "position": "left" } } } #导入文件 $settings=Get Content-Path somefile.json | ConvertFrom json #指定要更改的属性 $valueToChange=“menus.menu

我正在尝试编辑PowerShell中通过导入JSON文件创建的对象。然后我尝试使用点符号来访问或修改对象的属性

例如,下面是一个JSON示例和一个代码片段

{
  "menus": {
    "menu1": {
        "position": "left"
    }
  }
}
#导入文件
$settings=Get Content-Path somefile.json | ConvertFrom json
#指定要更改的属性
$valueToChange=“menus.menu1.position”
$value=“左”
#根据上述变量设置适当的值
$settings.$valueToChange=$value
上述情况给了我:

异常设置“menus.menu1.position”:“在此对象上找不到属性“menus.menu1.position”。请验证该属性存在并且可以设置。”

然而,如果我在没有点符号中的变量的情况下做完全相同的事情,它是有效的

#导入文件
$settings=Get Content-Path somefile.json | ConvertFrom json
#指定要更改的属性
$value=“左”
#根据上述变量设置适当的值,但使用硬编码点符号
$settings.menus.menu1.position=$value
我想这与变量是字符串或类似的变量有关,但问题是我需要通过编程计算点符号来设置文件中的值,或者至少允许用户指定它

实际上,我现在已经解决了这个问题(完全避免使用这种方法),但我想看看这是否可行


即使是一个干净的点表示法的替代方案也很好。我之所以选择它,唯一的原因是因为我真正的JSON对象非常复杂,点表示法非常简单易懂。

除非使用
调用表达式,否则在PowerShell中您不可能尝试这样做(即)

您可以使用递归函数,例如:

function Set-Property($Json, $Path, $Value) {
    $first, $rest = $Path
    if ($rest) {
        Set-Property -Json $Json.$first -Path $rest -Value $Value
    } else {
        $Json.$first = $Value
    }
}

$valueToChange = 'menus.menu1.position'.Split('.')
$newValue = 'left'

Set-Property -Json $settings -Path $valueToChange -Value $newValue

请注意,这只是一个非常基本的草稿,没有任何错误处理。

除非您使用
调用表达式,否则在PowerShell中不可能执行您试图执行的操作

您可以使用递归函数,例如:

function Set-Property($Json, $Path, $Value) {
    $first, $rest = $Path
    if ($rest) {
        Set-Property -Json $Json.$first -Path $rest -Value $Value
    } else {
        $Json.$first = $Value
    }
}

$valueToChange = 'menus.menu1.position'.Split('.')
$newValue = 'left'

Set-Property -Json $settings -Path $valueToChange -Value $newValue
请注意,这只是一个非常基本的草稿,没有任何错误处理。

这似乎可行(编辑:我后来发现它不可行):

或否:

dir variable:sett*

Name                           Value
----                           -----
settings                       @{menus=}
settings.menus.menu1.position  right
这是可行的,尽管我不确定它是否方便:

$value = 'right'
$prop1,$prop2,$prop3 = echo menus menu1 position
$settings.$prop1.$prop2.$prop3 = $value
$settings.menus

menu1
-----
@{position=right}
这似乎有效(编辑:我后来发现无效):

或否:

dir variable:sett*

Name                           Value
----                           -----
settings                       @{menus=}
settings.menus.menu1.position  right
这是可行的,尽管我不确定它是否方便:

$value = 'right'
$prop1,$prop2,$prop3 = echo menus menu1 position
$settings.$prop1.$prop2.$prop3 = $value
$settings.menus

menu1
-----
@{position=right}

OP希望更新导入的JSON数据,而不是在JSON对象树中定义一个以特定路径命名的变量。@AnsgarWiechers我认为它会起作用。我添加了另一种方法。您的第一种方法无法在b/c中起作用,否则就不可能在属性名称中包含点。您的第二种方法适用于此特定示例e、 但据我所知,OP希望能够指定任意路径。OP希望更新导入的JSON数据,而不是在JSON对象树中定义一个以特定路径命名的变量。@AnsgarWiechers我认为它会起作用。我添加了另一种方法。您的第一种方法无法在b/c模式下工作,否则就不可能有适当的rty名称中有点。您的第二种方法适用于这个特定的示例,但据我所知,OP希望能够指定任意路径。非常感谢这一点,我几乎完全采用了您上面建议的递归函数方法,只是做了一些小改动。我没有意识到这是重复的,我这是因为我没有用与其他人类似的方式表达我的问题……抱歉。做得很好(你已经有了我的+1)你甚至可以考虑调用函数<代码>设置属性,因为它应该为任何对象的属性路径工作。多谢了,我用上面提到的递归函数方法,几乎只是用一些小的变化。我没意识到这是一个复制品,我猜是因为我没有说过我的Quy。stion以类似于其他人的方式…道歉。做得很好(你已经有了我的+1)您甚至可以考虑调用函数<代码> SET属性,因为它应该与任何对象的属性路径一起工作。相关问题涵盖了包含属性路径的字符串获取嵌套属性值的方面:相关问题,涉及通过包含PR的字符串获得嵌套属性值的方面。属性路径: