【问题标题】:How to replace a property in a json file in powershell如何在powershell中替换json文件中的属性
【发布时间】:2019-03-16 23:48:06
【问题描述】:

我很难在 powershell 中读取 JSON 文件、替换值并写回文件或文件。

鉴于以下情况:

[Object]$QuickJson = @'
{
    "swagger": "1.0",
    "info": {
        "version": "0.0.1",
        "title": "this is a title",
        "description": "this is a description"
    },
    "basePath": "/test",   
    "paths" : {
        "/GetSomething": {
            "get": {
                "name" : "test01"
            }
        },
        "/GetSomethingElse" : {
            "get": {
                "name" : "test02"
            }
        },
        "/GetAnotherThing": {
            "get": {
                "name" : "test03"
            }
        }
    }
}
'@

我在这里感兴趣的是用其他东西替换“路径”对象中的值。我读取了文件并且可以使用我正在尝试的方法访问该对象:

[object]$MyPSJson = ConvertFrom-Json -InputObject $QuickJson

foreach($info in $MyPSJson.paths.PSObject.Properties)
{
    $path = $info.Name
    Write-Host "path: $path"
    $info.Name = "$path?code=fsfsfsfsfsfdfds"

    Write-Host $info.Name 
}

我不知道那些“路径”会是什么,我需要获取现有值并向其附加一个代码值,因此我需要能够遍历所有路径并进行替换。当我尝试上述方法时,出现错误:

路径:/GetSomething --“名称”是只读属性。在 C:\scripts\test.ps1:44 char:5 + $info.Name = "$path?code=fsfsfsfsfsfdfds" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : PropertyAssignmentException

我已经尝试了几种不同的方法,但还没有提出一个好的或可行的解决方案。非常感谢任何帮助或指出正确的方向。

【问题讨论】:

  • 你只是改变路径名吗?
  • Name 字段的类型为 System.Management.Automation.PSNoteProperty,它是只读的。您需要向 paths 孩子添加额外的成员。
  • @ArcSet 是的,我只需要更改路径名
  • @TheIncorrigible1 是的,这就是我遇到的问题,这就是为什么我相信/知道这不是正确的方法,可能应该以其他方式来做,只是不知道该怎么做
  • 要做你想做的事,我怀疑你需要将对象转换为哈希表,然后替换/转换回 json。

标签: json powershell


【解决方案1】:

除了对我有用的公认答案之外,我还找到了另一种最初建议的方法,即使用哈希表:

function Convert-JsonFileToHashTable([string]$file) {
    $text = [IO.File]::ReadAllText($file)
    $parser = New-Object Web.Script.Serialization.JavaScriptSerializer
    $parser.MaxJsonLength = $text.length
    $hashtable = $parser.Deserialize($text, @{}.GetType())

    return $hashtable
}

$hashtable = Convert-JsonFileToHashTable (Resolve-Path -Path $DefinitionFile)

$keys = New-Object System.Collections.ArrayList($null)
$keys.AddRange($hashtable["paths"].Keys)
foreach ($key in $keys) 
{
    $newPath = $key + "?code=$Code"
    $hashtable["paths"].$newPath = $hashtable["paths"].$key
    $hashtable["paths"].Remove($key) | Out-Null
}

$json = $hashtable | ConvertTo-Json -Depth 20
Write-Output $json | Out-File $newFile -Encoding utf8

【讨论】:

    【解决方案2】:

    尝试以下(PSv3+):

    $MyPSJson.paths = $MyPSJson.paths.psobject.properties |
      ForEach-Object { $renamedProps = [ordered] @{} } { 
        $renamedProps[$_.Name + '?foo=bar&baz=bam'] = $_.Value
      } { [pscustomobject] $renamedProps }
    

    出于技术上的需要,这重新创建 .paths 对象并修改了属性名称。

    它通过枚举原始属性,将修改后的名称下的值添加到有序哈希表中,在管道完成时将其转换为自定义对象 ([pscustomobject])。


    至于你尝试了什么

    给定对象的属性不能重命名 - 只能更改其属性的

    因此,您必须使用所需的新属性名称和与原始属性相同的值创建一个 new 对象。

    顺便说一句:[object] 强制转换在 PowerShell 中毫无意义 - 这是一个有效的无操作。
    相比之下,[pscustomobject] 转换可用于创建[pscustomobject] 实例从 [ordered] 哈希表,这是上面使用的技术;从其他类型进行强制转换又是一个虚拟的无操作。

    【讨论】:

      【解决方案3】:

      您可以做一些与现在非常相似的事情,只是不更改现有属性,而是记录初始属性,添加具有所需修改的新属性,然后将 $MyPSJson.paths 设置为自身,不包括旧属性,所以它所拥有的只是新属性。

      #Find initial paths
      $Paths=$MyPSJson.paths.psobject.Properties.Name
      
      #Add new paths with the modification to the name, and set the value to the same as the old path
      $Paths|%{Add-Member -InputObject $MyPSJson.paths -NotePropertyName "$_`?code=fsfsfsfsfsfdfds" -NotePropertyValue $MyPSJson.paths.$_}
      
      #Set the paths object to itself, excluding the original paths
      $MyPSJson.paths = $MyPSJson.paths|Select * -ExcludeProperty $Paths
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-12
        • 1970-01-01
        • 2021-05-13
        • 2018-12-11
        • 2020-10-16
        • 1970-01-01
        • 2021-12-26
        • 2022-11-17
        相关资源
        最近更新 更多