唯物是真 @Scaled_Wurm

プログラミング(主にPython2.7)とか機械学習とか

jqコマンドでJSONをCSVに変換する

前に以下のニコニコ動画のデータセットの記事でも使いましたが、jqコマンドJSONを変形したり一部を抽出したりするのにとても便利なコマンドです

ニコニコ動画のデータセットが公開されたらしい - 唯物是真 @Scaled_Wurm

マニュアルを見ると、条件に応じた処理とか最大値を求めるとか意外と複雑な機能も使うことができます
jq Manual

軽量JSONパーサー『jq』のドキュメント:『jq Manual』をざっくり日本語訳してみました | Developers.IO

また以下のサイトでオンライン上で試せます
jq play

JSONCSVに変換

JSONCSVに直したい時があって使い方を調べたのでメモしておきます

単純な例

まずは単純に以下のようなJSONCSVに変換します

{"key1": 1, "key2": 2}
方法1 - 文字列展開

文字列中の\()の中身は展開されます
".属性名"の形で好きな属性を好きな順番で出力できます
入れ子になっている場合も".属性名1.属性名2"とつなげて書けばよいです

echo {"key1": 1, "key2": 2} | jq -r "\(.key1),\(.key2)"

jqに"-r"を指定しないと出力がダブルクォーテーション""で囲まれて出てくるので注意

ちなみにWindowsコマンドプロンプトで動かしたら"error: syntax error, unexpected INVALID_CHARACTER, expecting $end"というエラーが出ましたが、例えば以下のように適切にエスケープすれば動きます('は使えない)

echo {"key1": 1, "key2": 2} | jq -r "\"\(.key1),\(.key2)\""

方法2 - 配列に変換してから@csvで出力する方法

入力が配列であれば@csvcsv形式で出力できます

echo {"key1": 1, "key2": 2} | jq -r "[.key1, .key2] | @csv"

フラットな構造のJSONであれば以下のようにしてすべての値をキーの昇順で出力できます

echo {"key1": 1, "key2": 2} | jq -r "to_entries | [.[].value] | @csv"

繰り返し構造を持つ例

次にJSON中に配列がある場合です

{
    "key1": 1,
    "key2": [1, 2, 3, 4]
}

まずは配列を全部展開してしまう方法です

echo {"key1": 1, "key2": [1, 2, 3, 4]} | jq -r "[.key1, .key2[]] | @csv"

以下のように出力されます

1,1,2,3,4

次に配列を各要素ごとに展開する方法です
"{key1, key2: .key2[]}"の部分で、key1の要素とkey2の配列のうちの1つの組み合わせのオブジェクトを作っています

echo {"key1": 1, "key2": [1, 2, 3, 4]} | jq -r "{key1, key2: .key2[]} | [.key1, .key2] | @csv"

以下のように出力されます

1,1
1,2
1,3
1,4