4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PowerShellのみでpretty JSON

Last updated at Posted at 2017-12-27

PowerShellのみでJSONの Pretty Print を実現してみました。

モチベーション

  • PowerShell標準の ConvertTo-Json のフォーマットが横に長いのが気に入らない。
  • 外部のライブラリなしにスクリプトだけポンと置いて手軽に使いたい。
    • .NETなので Newtonsoft とか読み込んでも良いけどライブラリ握るのもちょっとヤなので。

内容

ソースコードは gist にアップしたので全文はそちらを参照。

2018/01/04 追記
よくよく考えればインデント位置に合わせるよりカッコ数えた方が楽なことに気づいたのでロジック修正。
初版のソースは こちら

元のオブジェクト
$person = @{
    name = 'kitamin'
    age = '3x'
    hobbies = @(
        'game'
        'programming'
    )
}
PowerShell標準のJSON変換
# 前のカッコの位置から次のインデントが始まるので、プロパティ名が長いほどインデントが大きくなる _(:3」∠)_
PS> ConvertTo-Json $person
{
    "name":  "kitamin",
    "age":  "3x",
    "hobbies":  [
                    "game",
                    "programming"
                ]
}
実装した関数、デフォルトはスペース4つでインデント
PS> ConvertTo-PrettyJson $person
{
    "name":  "kitamin",
    "age":  "3x",
    "hobbies":  [
        "game",
        "programming"
    ]
}
インデント幅も変えられる
PS> ConvertTo-PrettyJson $person -IndentWidth 2
{
  "name":  "kitamin",
  "age":  "3x",
  "hobbies":  [
    "game",
    "programming"
  ]
}
既存のJSON文字列も再整形できる
PS> ConvertTo-PrettyJson -Json @'
{
    "name":  "kitamin",
    "age":  "3x",
    "hobbies":  [
                    "game",
                    "programming"
                ]
}
'@

{
    "name":  "kitamin",
    "age":  "3x",
    "hobbies":  [
        "game",
        "programming"
    ]
}

仕組み

ConvertTo-Json で整形されたJSON文字列をベースに インデントの位置を力技で整形してます。
以下のルールでインデントを制御しています (2018/01/04 修正)。

  • 開きカッコ([, {)が見つかったら 次の行 からインデントを一つ下げる
  • 閉じカッコ(], })が見つかったら 今の行 からインデントを一つ上げる
ConvertTo-PrettyJson(該当箇所)
if ($line -match '^\s*[\}\]]') {
    # カッコが閉じた
    $indentCount--
}

# 出力行の整形
$output = ($indent * $indentCount) + $line.Trim()
Write-Output $output

if ($line -match '[\{\[]\s*$') {
    # カッコが開いた
    $indentCount++
}

JSON文字列を渡した場合は書式を整えるために内部で ConvertFrom-Json -> ConvertTo-Json とやっているのでかなり効率は悪いけど、
今のところ細かいオブジェクトを表示用整形する時に使いたかっただけなのであまり問題にはなってないです。


おまけ

そのうち内部処理をクラス化するかも。
PowerShellのクラスパフォーマンスとか実地取ってみたいのでそのサンプルとして。

2018/01/04
内部処理のクラス化 をしてみた。
パフォーマンスとかは別の記事で書くかもです。


4
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?