使用PowerShell脚本对json响应进行排序

时间:2017-04-05 17:23:49

标签: json sorting powershell

我正在进行REST API调用并获得json响应。我想从响应中获得最高的字符串。

$x = Invoke-RestMethod -Method Get -Uri $r

返回类似这样的内容

    {
  "results": [
    {
      "uri": "h//foo/test.1.0.19.4.n"
    },
    {
      "uri": "h://foo/test.1.0.20.6.n"
    },
    {
      "uri": "h://foo/test.1.0.20.7.n"
    }
  ]
}

从此我想提取"test.1.0.20.7.n",这是.19.20之间的最大值,当我比较.7的最后一个.6时}}

我一直在尝试使用

$X| Select uri |  Sort-Object uri 

它只是打印

test...
test...
test...

2 个答案:

答案 0 :(得分:1)

提供Remko's answer的替代方案:

  • 使用类型[version]来实现所需的排序:

    • [version]执行适当的逐个组件比较以进行排序。
    • 除了更直接地实现基础概念之外,这还有一个优点,就是不必担心溢出整数数据类型。
  • 仅提取感兴趣的子字符串,例如test.1.0.20.7.n

# Parse sample JSON input into a PS custom object.
$objFromJson = @'
    {
  "results": [
    {
      "uri": "h://foo/test.1.0.19.4.n"
    },
    {
      "uri": "h://foo/test.1.0.20.7.n"
    },
    {
      "uri": "h://foo/test.1.0.20.6.n"
    }
  ]
}
'@ | ConvertFrom-Json

# Sort the results by the version-number-like tokens embedded in the `uri`
# property of the elements of the collection stored in the `.result` property,
# output the one with the highest version number, then remove
# the URL path prefix with `Split-Path`
$objFromJson.results | 
 Sort-Object -Descending {[version] ($_.uri -replace '^.+(\d+\.\d+\.\d+\.\d+).+$', '$1')} |
   Select-Object -First 1 |
     Split-Path -Leaf -Path { $_.uri }

以上产量:

test.1.0.20.7.n    

在上面的-replace操作中:

  • 正则表达式^.+(\d+\.\d+\.\d+\.\d+).+$匹配整个URI并捕获捕获组中类似版本的部分(例如1.0.19.4),
  • 然后将其值($1)用作替换字符串,它实际上仅返回类似于版本的部分,然后[version]强制转换为该类型。

@Remko建议使正则表达式更加灵活,以防您需要将类似字符串的字符串与更少的组件匹配。在实践中,从字符串转换为[version]限制为2到4个组件(例如,字符串1.21.2.31.2.3.4工作,但11.2.3.4.5不要,你可以使用以下正则表达式建模:
'^.+((\d+\.){1,3}\d+).+$'

如果您的类似字符串的字符串包含更多组件,则必须实现自己的排序(如果解释版本中的所有数字而产生的数字,则Remko的答案可能有效字符串作为单个整数不会变得太大。)

答案 1 :(得分:0)

您可以通过在我发表关于earlier的博客中利用表达式“自定义”排序来实现此目的。以下示例适用于我:

$json = @"
    {
  "results": [
    {
      "uri": "h://foo/test.1.0.19.4.n"
    },
    {
      "uri": "h://foo/test.1.0.20.7.n"
    },
    {
      "uri": "h://foo/test.1.0.20.6.n"
    }
  ]
}
"@

$obj = ConvertFrom-Json $json

$obj.results | Sort-Object -Property @{Expression={[int]($_.uri -replace "\D", "")}} | select -Last 1

输出:

uri                    
---                    
h://foo/test.1.0.20.7.n

使用此数据集:

    {
  "results": [
    {
      "uri": "h://foo/test.1.0.19.4.n"
    },
    {
      "uri": "h://foo/test.1.1.5.7.n"
    },
    {
      "uri": "h://foo/test.1.2.20.1.n"
    },
    {
      "uri": "h://foo/test.1.0.20.7.n"
    },
    {
      "uri": "h://foo/test.1.0.20.6.n"
    }
  ]
}

结果是:

uri                    
---                    
h://foo/test.1.2.20.1.n