json Powershell按字母顺序对PSObject排序

pnwntuvh  于 2023-02-26  发布在  Shell
关注(0)|答案(3)|浏览(130)

给定一个从json(foo.json)创建的自定义powershell对象(bar)
你将如何按键的字母顺序对对象进行排序?

foo.json
{
  "bbb": {"zebras": "fast"},
  "ccc": {},
  "aaa": {"apples": "good"}
}

期望输出

foo.json
{
  "aaa": {"apples": "good"},
  "bbb": {"zebras": "fast"},
  "ccc": {}
}

示例

$bar = get-content -raw foo.json | ConvertFrom-Json  
$bar.gettype()  

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

我使用sort-object尝试了以下方法
$bar = $bar | Sort
$bar = $bar | Sort-Object
Sort-Object -InputObject $bar
Sort-Object -InputObject $bar -Property Name
Sort-Object -InputObject $bar -Property @{Expression="Name"}
Sort-Object -InputObject $bar -Property @{Expression={$_.PSObject.Properties.Name}}
我还尝试过将PSObject转换为哈希表(哈希表似乎自动根据名称排序),然后将该哈希表转换回json,但它再次失去了顺序。

$buzz = @{}
$bar.psobject.properties |Foreach { $buzz[$_.Name] = $_.Value }
ConvertTo-Json $buzz -Depth 9
    • 更新**

更改foo.json以包含值和键

vuv7lop3

vuv7lop31#

正如Mathias R. Jessen所指出的,这里没有要排序的 * 集合 *,只有一个对象 *,其属性 * 需要排序,因此需要通过Get-Member进行 * 反射 * 以获取对象的属性:

$bar = get-content -raw foo.json | ConvertFrom-Json

# Build an ordered hashtable of the property-value pairs.
$sortedProps = [ordered] @{}
Get-Member -Type  NoteProperty -InputObject $bar | Sort-Object Name |
  % { $sortedProps[$_.Name] = $bar.$($_.Name) }

# Create a new object that receives the sorted properties.
$barWithSortedProperties = New-Object PSCustomObject
Add-Member -InputObject $barWithSortedProperties -NotePropertyMembers $sortedProps

更精简的版本使用-pv-PipelineVariable)“缓存”ConvertFrom-Json生成的未排序自定义对象:

$barSortedProps = New-Object PSCustomObject
Get-Content -Raw foo.json | ConvertFrom-Json -pv jo |
  Get-Member -Type  NoteProperty | Sort-Object Name | % { 
    Add-Member -InputObject $barSortedProps -Type NoteProperty `
               -Name $_.Name -Value $jo.$($_.Name)
  }
11dmarpk

11dmarpk2#

这个怎么样:

Function Sort-PSObject {
        [CmdletBinding()]
        Param(
            [Parameter(ValueFromPipeline=$true)]$inputString
        )
        process {
            ($inputString | out-string).trim() -split "`r`n" | sort
        }
}

可直接从管道发送

sbdsn5lh

sbdsn5lh3#

以下是@mklement0和@EricWeintraub的答案的综合版本:

Function Sort-PSObjectMembers {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline=$true)]$inputObj
    )
    process {
        $sortedProps = [ordered] @{}
        Get-Member -Type NoteProperty -InputObject $inputObj | Sort-Object Name | ForEach-Object { $sortedProps[$_.Name] = $inputObj.$($_.Name) }

        # Create a new object that receives the sorted properties.
        $sortedObj = New-Object PSCustomObject
        Add-Member -InputObject $sortedObj -NotePropertyMembers $sortedProps        

        return $sortedObj
    }
}

所以你可以这样使用它:

$elements | Sort-PSObjectMembers | ConvertTo-Json -Depth 32 | Out-File "elements.json" -Encoding utf8

相关问题