我有一个JSON格式的以下文件:
之前ConvertTo-JSON:
ConvertTo-JSON
[ { "Yura": { "Cashier": { "branch": "release/Retail-v4.0", "configuration": "RetailDemo Debug", "datetime_deployed": "Apr 18 2018 07:45:05", "deployed_by": "anonymous", "host": "cashier2-retail4.testing.aws.com", "job": "http://jenkins-testing.aws.com:8080/job/CashierDeployment", "lineserver": "", "messagebus": "", "product": "Cashier", "publish_profile": "cashier2.retail.dev.pubxml" }, "ContentManager": { "branch": "release/Retail-v3.31.1", "configuration": "RetailDemo Debug", "datetime_deployed": "Jan 17 2018 11:59:24", "deployed_by": "anonymous", "host": "contentmanager2-retail3.testing.aws.com", "job": "http://jenkins-testing.aws.com:8080/job/ContentManagerDeployment", "lineserver": "", "messagebus": "", "product": "ContentManager", "publish_profile": "..\\ContentManager.PublishProfiles\\contentmanager2.retail5.dev.pubxml" } } } ]
使用以下代码处理数据后:
$json = Get-Content 'D:\script\test.json' -encoding utf8 | ConvertFrom-Json $json.yura.ContentManager.branch = 'test'
我将JSON保存到另一个文件中:
$json | convertto-json | set-content "D:\script\test1.json" -encoding utf8
问题是,保存文件后,格式损坏了:
{ "Yura": { "Cashier": { "branch": "release/Retail-v4.0", "configuration": "RetailDemo Debug", "datetime_deployed": "Apr 18 2018 07:45:05", "deployed_by": "anonymous", "host": "cashier2-retail4.testing.aws.com", "job": "http://jenkins-testing.aws.com:8080/job/CashierDeployment", "lineserver": "", "messagebus": "", "product": "Cashier", "publish_profile": "cashier2.retail.dev.pubxml" }, "ContentManager": { "branch": "test", "configuration": "RetailDemo Debug", "datetime_deployed": "Jan 17 2018 11:59:24", "deployed_by": "anonymous", "host": "contentmanager2-retail3.testing.aws.com", "job": "http://jenkins-testing.aws.com:8080/job/ContentManagerDeployment", "lineserver": "", "messagebus": "", "product": "ContentManager", "publish_profile": "..\\ContentManager.PublishProfiles\\contentmanager2.retail5.dev.pubxml" } } }
我的问题是-如何在PowerShell中保留源格式?
由于您的原始json包含一个只有一个元素的数组,因此PowerShell会将其压缩为仅一个元素。如果在输出中希望再次将其作为数组,请使用rokumaru的好答案。
但是,PowerShell ConvertTo-Json不会生成格式精美的json,为此,我前段时间编写了一个辅助函数:
ConvertTo-Json
function Format-Json { <# .SYNOPSIS Prettifies JSON output. .DESCRIPTION Reformats a JSON string so the output looks better than what ConvertTo-Json outputs. .PARAMETER Json Required: [string] The JSON text to prettify. .PARAMETER Minify Optional: Returns the json string compressed. .PARAMETER Indentation Optional: The number of spaces (1..1024) to use for indentation. Defaults to 4. .PARAMETER AsArray Optional: If set, the output will be in the form of a string array, otherwise a single string is output. .EXAMPLE $json | ConvertTo-Json | Format-Json -Indentation 2 #> [CmdletBinding(DefaultParameterSetName = 'Prettify')] Param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] [string]$Json, [Parameter(ParameterSetName = 'Minify')] [switch]$Minify, [Parameter(ParameterSetName = 'Prettify')] [ValidateRange(1, 1024)] [int]$Indentation = 4, [Parameter(ParameterSetName = 'Prettify')] [switch]$AsArray ) if ($PSCmdlet.ParameterSetName -eq 'Minify') { return ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100 -Compress } # If the input JSON text has been created with ConvertTo-Json -Compress # then we first need to reconvert it without compression if ($Json -notmatch '\r?\n') { $Json = ($Json | ConvertFrom-Json) | ConvertTo-Json -Depth 100 } $indent = 0 $regexUnlessQuoted = '(?=([^"]*"[^"]*")*[^"]*$)' $result = $Json -split '\r?\n' | ForEach-Object { # If the line contains a ] or } character, # we need to decrement the indentation level unless it is inside quotes. if ($_ -match "[}\]]$regexUnlessQuoted") { $indent = [Math]::Max($indent - $Indentation, 0) } # Replace all colon-space combinations by ": " unless it is inside quotes. $line = (' ' * $indent) + ($_.TrimStart() -replace ":\s+$regexUnlessQuoted", ': ') # If the line contains a [ or { character, # we need to increment the indentation level unless it is inside quotes. if ($_ -match "[\{\[]$regexUnlessQuoted") { $indent += $Indentation } $line } if ($AsArray) { return $result } return $result -Join [Environment]::NewLine }
像这样使用它:
$json = Get-Content 'D:\script\test.json' -Encoding UTF8 | ConvertFrom-Json $json.yura.ContentManager.branch = 'test' # recreate the object as array, and use the -Depth parameter (your json needs 3 minimum) ConvertTo-Json @($json) -Depth 3 | Format-Json | Set-Content "D:\script\test1.json" -Encoding UTF8 # instead of using '@($json)' you can of course also recreate the array by adding the square brackets manually: # '[{0}{1}{0}]' -f [Environment]::NewLine, ($json | ConvertTo-Json -Depth 3) | # Format-Json | Set-Content "D:\script\test1.json" -Encoding UTF8