在 Powershell 中转换为 JSON 时如何更改制表符宽度
How to change tab width when converting to JSON in Powershell
我正在 Powershell 中创建一个 JSON,我想在构建它时设置自定义制表符宽度(而不是默认的 4 个空格,我只想设置 2 个空格)。
我这样做是因为:
- 实际 JSON(不是下面示例中显示的那个)相当大(超过 100k 行),如果没有归档,它的大小相当大;如果我减小制表符宽度,尺寸会显着减小。
- 实际 JSON 有 5+ 个节点的深度!
- 我不能使用 -Compress 因为 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
Result with tab width = 4 white space characters.
{
"Phone": "SomePhone",
"Description": "Lorem ipsum dolor..",
"Price": 99.99
}
I tried compression but it doesn't give control over compression level (how agressive compression should be)
$object | ConvertTo-Json -Compress
Result compressed, obviously.
{"Phone":"SomePhone","Description":"Lorem ipsum dolor..","Price":99.99}
What I am trying to achieve: result with tab width = 2 white space characters.
{
"Phone": "SomePhone",
"Description": "Lorem ipsum dolor..",
"Price": 99.99
}
What I've tried so far is in the pseudo code below. I'm still in the loop. Please get me out of there :)
while (1) {
Google, Whosebug
Try Stuff found
Tweak stuff found
if (Correct answer) {
break
}
}
以下代码将缩进大小减半:
$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"
这里有一个简单的方法:
$data_json | convertto-json -depth 100 |
foreach-object {$_ -replace "(?m) (?<=^(?: )*)", "`t" } |
set-content 'output.json'
如果您将多个对象传递给 ConvertTo-JSON.
,则 foreach-object 会捕获
将 "`t"
更改为您想要的缩进。
因为 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 '": (["{[])', '": ' -replace ': ', ': ')
if ($_ -match '[\{\[]\s*$') {
# This line ends with [ or {, increment the indentation level
$indent++
}
$line
}) -Join "`n"
}
用法:$foo | ConvertTo-Json | Format-Json
您可以将 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
我正在 Powershell 中创建一个 JSON,我想在构建它时设置自定义制表符宽度(而不是默认的 4 个空格,我只想设置 2 个空格)。
我这样做是因为:
- 实际 JSON(不是下面示例中显示的那个)相当大(超过 100k 行),如果没有归档,它的大小相当大;如果我减小制表符宽度,尺寸会显着减小。
- 实际 JSON 有 5+ 个节点的深度!
- 我不能使用 -Compress 因为 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
Result with tab width = 4 white space characters.
{
"Phone": "SomePhone",
"Description": "Lorem ipsum dolor..",
"Price": 99.99
}
I tried compression but it doesn't give control over compression level (how agressive compression should be)
$object | ConvertTo-Json -Compress
Result compressed, obviously.
{"Phone":"SomePhone","Description":"Lorem ipsum dolor..","Price":99.99}
What I am trying to achieve: result with tab width = 2 white space characters.
{
"Phone": "SomePhone",
"Description": "Lorem ipsum dolor..",
"Price": 99.99
}
What I've tried so far is in the pseudo code below. I'm still in the loop. Please get me out of there :)
while (1) {
Google, Whosebug
Try Stuff found
Tweak stuff found
if (Correct answer) {
break
}
}
以下代码将缩进大小减半:
$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"
这里有一个简单的方法:
$data_json | convertto-json -depth 100 |
foreach-object {$_ -replace "(?m) (?<=^(?: )*)", "`t" } |
set-content 'output.json'
如果您将多个对象传递给 ConvertTo-JSON.
,则 foreach-object 会捕获将 "`t"
更改为您想要的缩进。
因为 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 '": (["{[])', '": ' -replace ': ', ': ')
if ($_ -match '[\{\[]\s*$') {
# This line ends with [ or {, increment the indentation level
$indent++
}
$line
}) -Join "`n"
}
用法:$foo | ConvertTo-Json | Format-Json
您可以将 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