使用带点标记的变量编辑/访问Powershell对象

enyaitl3  于 2023-03-18  发布在  Shell
关注(0)|答案(3)|浏览(126)

我试图在PowerShell中编辑一个通过导入JSON文件创建的对象,然后尝试使用点标记法访问或修改对象的属性。
例如,下面是JSON示例和代码片段

{
  "menus": {
    "menu1": {
        "position": "left"
    }
  }
}
# Import the file
$settings = Get-Content -Path somefile.json | ConvertFrom-Json

# Specify the property to change
$valueToChange = "menus.menu1.position"
$value = "left"

# Set the appropriate value according to the variables above
$settings.$valueToChange = $value

以上给出了:
设置“menus.menu1.position”时出现异常:在此对象上找不到属性“menus.menu1.position”。请验证该属性是否存在并且可以设置。
然而,如果我做完全相同的事情,而不使用点符号中的变量,它就可以工作。

# Import the file
$settings = Get-Content -Path somefile.json | ConvertFrom-Json

# Specify the property to change
$value = "left"

# Set the appropriate value according to the variables above but with a hard coded dot notation
$settings.menus.menu1.position = $value

我猜这与变量是字符串或类似的变量有关,但问题是我需要通过编程计算点符号,以设置文件中的值,或至少允许用户指定它。
实际上,我现在已经解决了这个问题(完全避免了这种方法),但我想看看这是否可能。
即使是一个干净的点符号的替代品也会很好地看到。我一开始使用它的唯一原因是因为我真实的的JSON对象相当复杂,而点符号非常简单,很容易遵循。

k5hmc34c

k5hmc34c1#

除非您使用Invoke-Expression(即strongly discouraged),否则您在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

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

wlzqhblo

wlzqhblo2#

这似乎行得通(编辑:我后来发现它没有):

$settings = Get-Content -Path somefile.json | ConvertFrom-Json
$valueToChange = "menus.menu1.position"
$value = "right"
set-variable settings.$valuetochange $value
get-variable settings.$valuetochange

Name                           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}
ubby3x7f

ubby3x7f3#

使用$()或() Package 变量语法适用于5.1及更高版本。示例:

$settings = Get-Content -Path "jsonData.json" | ConvertFrom-Json

$p1 = "menus"
$p2 = "menu1"
$p3 = "position"
$newVal = "right"

write-host $settings.$($p1).$($p2).$($p3)
$settings.$($p1).$($p2).$($p3) = $newVal
write-host $settings.$($p1).$($p2).$($p3)

---------------或-----------

write-host $settings.($p1).($p2).($p3)
$settings.($p1).($p2).($p3) = $newVal
write-host $settings.($p1).($p2).($p3)

相关问题