programing

Powershell에서 JSON으로 변환할 때 탭 너비를 변경하는 방법

lastmoon 2023. 8. 30. 21:57
반응형

Powershell에서 JSON으로 변환할 때 탭 너비를 변경하는 방법

저는 Powershell에서 JSON을 만들고 있으며 빌드할 때 사용자 지정 탭 너비를 설정하고 싶습니다(기본 흰색 공간 4개 대신 흰색 공간 2개만 설정).

다음과 같은 이유로 이 작업을 수행합니다.

  • 실제 JSON(아래 샘플에 제시된 것이 아님)은 상당히 크고(100k 이상의 행), 보관되지 않으면 크기가 상당히 큽니다. 탭 너비를 줄이면 크기가 크게 줄어듭니다.
  • 실제 JSON의 깊이는 5개 이상입니다!
  • JSON은 사람이 읽을 수 있어야 하므로 -Compress를 사용할 수 없습니다.
  • 네, 동의합니다. 보관하면 크기가 크게 줄어들지만 보관하지 않은 것도 필요합니다.

샘플 코드:

$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
    }
}

PowerShell의 ConvertTo-Json은 비결정론적 들여쓰기를 생성하므로 현재 답변에서는 데이터 구조의 각 깊이에 대해 정확히 두 개의 공간이 있는 JSON을 생성하지 않습니다.

각 중첩 데이터 수준을 엔클로저 수준보다 정확히 두 공간 더 들여쓰려면 들여쓰기를 다시 작성해야 합니다. (중요한 것은, 이것이 PowerShell 6에서 수정된 것처럼 보인다는 것입니다.

저만의 솔루션을 작성한 후, 여기 페이스북의 Daniel Lo Nigro(Daniel15)의 GitHub에서 거의 동일한 솔루션을 발견했습니다.His는 Piped 입력을 취할 수 있는 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' -replace ':  ', ': ')
        if ($_ -match '[\{\[]\s*$') {
            # This line ends with [ or {, increment the indentation level
            $indent++
        }
        $line
    }) -Join "`n"
}

용도:$foo | ConvertTo-Json | Format-Json

다음 코드는 들여쓰기 크기를 절반으로 줄입니다.

$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"

뉴턴소프트를 사용할 수 있습니다.Json with PowerShell.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

간단한 방법은 다음과 같습니다.

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

둘 이상의 개체를 ConvertTo-JSON으로 전달하면 각 개체에 대한 포어가 잡힙니다.

변할내용을 합니다."`t"당신이 들여쓰기로 하고 싶은 모든 것.

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

$json = $json | ConvertFrom-Json | ConvertTo-Json

$len = 0
(($json -split '\r\n' |
% {
    $line = $_
    
    if ($_.contains('}') -or $_.contains(']')) {
    $len--
    }

    $line = '  ' * $len + $line.TrimStart()
      
    if ($_.contains('{') -or $_.contains('[')) {
    $len++
    }

    $line
}) -join "`r`n")

언급URL : https://stackoverflow.com/questions/33145377/how-to-change-tab-width-when-converting-to-json-in-powershell

반응형