🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

解決済

2回答

5576閲覧

PowerShell ConvertFrom-Jsonでjsonファイルを読み込むと、配列が消えてしまう

eri0315

総合スコア23

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

0グッド

1クリップ

投稿2019/12/16 13:03

前提・実現したいこと

ConvertFrom-Jsonで読み込んだJsonファイルを、
ConvertTo-Jsonで出力する時、配列が消えてしまうため、
配列を消さずに出力したいです。

該当のソースコード

InputJSON

1[ 2 { 3 "hoge": { 4 "foo": "bar" 5 } 6 } 7] 8

PowerShell

1 2$hoge = gc $json_file -Encoding UTF8 | ConvertFrom-Json 3 4$Main_process 5 6$hoge | ConvertTo-Json -Depth 100 7

試したこと

上記のソースを実行すると、
トップレベルに存在する配列が消えて出力されてしまいます。
トップレベルの配列が消えてしまうタイミングは、
JSONファイル読み込み時(ConvertFrom-Json)であると特定しているのですが、
なぜ、JSONファイルをConvertFrom-Jsonで読み込むと、
配列が消えてしまうのでしょうか。

補足情報(FW/ツールのバージョンなど)

PSVersion 5.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2019/12/16 13:58

$hoge.GetType() が Object[] なので、`ConvertFrom-Json`までは配列で来ています。
guest

回答2

0

ベストアンサー

Zuishinさんの回答は PowerShell 全般に言える話で、多くの場合Zuishinさんの回答で大丈夫です。

しかし、今回の場合は Windows PowerShell の ConvertTo-Json の挙動の罠もあるため、追加の対処が必要です(PowerShell Core では改善されているはずですが)。

なにが問題かというと、Zuishinさんの回答の方法では以下のような出力になってしまいます。

JSON

1{ 2 "value": [ 3 { 4 "hoge": { 5 "foo": "bar" 6 } 7 } 8 ], 9 "Count": 1 10}

最上位が valueCount を持つオブジェクトとなり、valueに配列が入ってしまいます。

PowerShellの配列はCountという本来の配列が持っていない特殊なプロパティを持っていることが原因です。

対処としては、一旦配列以外のコレクションに要素を入れ直す(以下1.のコード)ことですが、
以下の 2. のコードのようにInputObject に @() でくるんで渡しても意図する結果となりました。

PowerShell

1# 1. 一旦配列以外のコレクションに要素を入れ直す 2ConvertTo-Json -InputObject ([System.Collections.ArrayList]::Adapter($hoge)) -Depth 100 3 4# 2. InputObject に @() でくるんで渡す 5ConvertTo-Json -InputObject @($hoge) -Depth 100

JSON

1[ 2 { 3 "hoge": { 4 "foo": "bar" 5 } 6 } 7]

参考

Zuishinさんの回答にある一次元配列の罠について(やや古い記事ですが)

そろそろ PowerShell の一次配列の罠と回避について一言いっておくか - tech.guitarrapc.cóm

自分の回答にある、Countの挙動について

PowerShellのCountプロパティについてあれやこれや (2018年10月版) - しばたテックブログ

投稿2019/12/16 22:44

imihito

総合スコア2166

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

PowerShell

1ConvertTo-Json -InputObject $hoge -Depth 100

あるいは

PowerShell

1,$hoge | ConvertTo-Json -Depth 100

これでやってみてください。

PowerShell を使う上で嵌まる罠の一つで、パイプラインへの出力が複数のオブジェクトに展開されてしまいます。展開された結果一つのオブジェクトしかなかった場合、もともと一つであったものと区別がつきません。
対処法は前者のようにパイプラインを使わず直接引数にするか、後者のように配列でラップするかです。

投稿2019/12/16 21:09

編集2019/12/16 21:29
Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問