在Powershell中转换为JSON时如何更改选项卡宽度

时间:2015-10-15 09:54:34

标签: json powershell powershell-v4.0

我在Powershell中创建了一个JSON,我想在构建时设置自定义标签宽度(而不是默认的4个空格,我只想设置2个空格)。

我这样做是因为:

  • 实际的JSON(不是下面示例中提供的那个)非常大(100k +行),如果没有达到,它的大小相当大;如果我减小标签宽度,则尺寸减小值得注意。
  • 实际的JSON深度为5+个节点!
  • 我不能使用-Co​​mpress,因为JSON需要是人类可读的
  • 是的,我同意,如果存档,它的大小会大大减少,但我也需要它也没有归档。

示例代码:

$object = New-Object PSObject
Add-Member -InputObject $object -MemberType NoteProperty -Name Phone -Value "SomePhone"
Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.."
Add-Member -InputObject $object -MemberType NoteProperty -Name Price -Value 99.99

$object | ConvertTo-Json
  

选项卡宽度= 4个空格字符的结果。

{
    "Phone":  "SomePhone",
    "Description":  "Lorem ipsum dolor..",
    "Price":  99.99
}
  

我尝试过压缩,但它无法控制压缩级别(压缩程度应该如何)

$object | ConvertTo-Json -Compress
  

显然压缩了结果。

{"Phone":"SomePhone","Description":"Lorem ipsum dolor..","Price":99.99}
  

我想要实现的目标:标签宽度= 2个空白字符的结果。

{
  "Phone":  "SomePhone",
  "Description":  "Lorem ipsum dolor..",
  "Price":  99.99
}
  

到目前为止我尝试过的是下面的伪代码。我还在循环中。请让我离开那里:)

while (1) {
    Google, StackOverflow
    Try Stuff found 
    Tweak stuff found

    if (Correct answer) {
        break
    }
}

4 个答案:

答案 0 :(得分:6)

以下代码将缩进的大小减半:

$json = @"
{
    "Phone":  "SomePhone",
    "Description":  "Lorem ipsum dolor..",
    "Price":  99.99
}
"@

($json -split '\r\n' |
% {
  $line = $_
  if ($_ -match '^ +') {
    $len  = $Matches[0].Length / 2
    $line = ' ' * $len + $line.TrimStart()
  }
  $line
}) -join "`r`n"

答案 1 :(得分:1)

这是一个简单的方法:

$data_json | convertto-json -depth 100 |
    foreach-object {$_ -replace "(?m)  (?<=^(?:  )*)", "`t" } |
    set-content 'output.json'

如果将多个对象传递给ConvertTo-JSON,则会捕获foreach对象。

"`t"更改为您要使用缩进的方式。

答案 2 :(得分:1)

由于PowerShell的ConvertTo-Json会产生不确定的缩进,因此当前的答案将不会生成在数据结构中每个深度正好有两个空格的JSON。

要使嵌套数据的每个级别缩进比包围级别多两个空格,需要重建缩进。 (对于它的价值,在PowerShell 6中看起来像this was fixed

在编写了自己的解决方案后,我在GitHub上从Facebook的Daniel Lo Nigro(Daniel15)here找到了一个几乎相同的解决方案。他是一个PowerShell函数,可以接受管道输入。 (我使正则表达式匹配更具体一些,以减少意外匹配数据的可能性。)

# Formats JSON in a nicer format than the built-in ConvertTo-Json does.
function Format-Json([Parameter(Mandatory, ValueFromPipeline)][String] $json) {
    $indent = 0;
    ($json -Split "`n" | % {
        if ($_ -match '[\}\]]\s*,?\s*$') {
            # This line ends with ] or }, decrement the indentation level
            $indent--
        }
        $line = ('  ' * $indent) + $($_.TrimStart() -replace '":  (["{[])','": $1')
        if ($_ -match '[\{\[]\s*$') {
            # This line ends with [ or {, increment the indentation level
            $indent++
        }
        $line
    }) -Join "`n"
}

用法:$foo | ConvertTo-Json | Format-Json

答案 3 :(得分:0)

您可以将Newtonsoft.Json与PowerShell一起使用。您可以安装a module for it in PowerShell Gallery来方便地使用它。

示例:

if (!(Get-Module -ListAvailable -Name "newtonsoft.json")) {
    Install-Module -Name "newtonsoft.json" -Scope CurrentUser -Force
}

Import-Module "newtonsoft.json" -Scope Local

$JObject = [Newtonsoft.Json.Linq.JObject]::new(
    [Newtonsoft.Json.Linq.JProperty]::new("Phone", "SomePhone"),
    [Newtonsoft.Json.Linq.JProperty]::new("Description", "Lorem ipsum dolor.."),
    [Newtonsoft.Json.Linq.JProperty]::new("Price", 99.99));

$JObject.ToString()

生产

{
  "Phone": "SomePhone",
  "Description": "Lorem ipsum dolor..",
  "Price": 99.99
}

在使用json时,它还具有其他许多功能:https://www.newtonsoft.com/json/help/html/Introduction.htm