下記記事を参考にほぼほぼやりたいことはできたのですが、ハマったのでメモ。
[jq] JSONデータの特定階層にあるキー名のユニーク値を取得 - Qiita
https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
JSONファイル
行ごとにキーが同じだったり、違ったり、数も違うちょっと困ったJSONファイルがあるときに使えます。
{"hoge1": "hoge", "hoge2": 2, "hoge3": false}
{"hoge2": "hoge", "hoge3": 2, "hoge4": false, "hoge5": "FOO"}
{"hoge1": "hoge", "hoge2": 2, "hoge6": false}
いい感じのコマンド
> cat hoge.json | jq -s -r '[ .[] | keys ] | flatten | unique | .[]'
hoge1
hoge2
hoge3
hoge4
hoge5
hoge6
jq
の-s
オプションで配列にする
ファイル中に{...}{...}{...}
と[]
括りされず、,
区切りもないため、jq
の--slurp
(-s
)オプションで配列に放り込みます。
jq Manual (development version)
https://stedolan.github.io/jq/manual/
--slurp/-s:
Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once.
(Google翻訳)入力内の各JSONオブジェクトに対してフィルターを実行する代わりに、入力ストリーム全体を大きな配列に読み取り、フィルターを1回だけ実行します。
# -s オプションなし
> cat hoge.json | jq
{
"hoge1": "hoge",
"hoge2": 2,
"hoge3": false
}
{
"hoge2": "hoge",
"hoge3": 2,
"hoge4": false,
"hoge5": "FOO"
}
{
"hoge1": "hoge",
"hoge2": 2,
"hoge6": false
}
# -s オプションあり
> cat hoge.json | jq -s
[
{
"hoge1": "hoge",
"hoge2": 2,
"hoge3": false
},
{
"hoge2": "hoge",
"hoge3": 2,
"hoge4": false,
"hoge5": "FOO"
},
{
"hoge1": "hoge",
"hoge2": 2,
"hoge6": false
}
]
キー名だけ出力する
あとは上記記事と同じく[ .[] | keys ] | flatten | unique
でキー名を取得、平坦化して重複を取り除きます。
ちなみに平坦化しないとこんな感じになります。unique
が効きません。
> cat hoge.json | jq -s -r '[ .[] | keys ] | unique'
[
[
"hoge1",
"hoge2",
"hoge3"
],
[
"hoge1",
"hoge2",
"hoge6"
],
[
"hoge2",
"hoge3",
"hoge4",
"hoge5"
]
]
最後に.[]
で出力し、jq
コマンドの--raw-output
(-r
)オプションでダブルクォーテーションを取り除きます。
jq Manual (development version)
https://stedolan.github.io/jq/manual/
--raw-output / -r:
With this option, if the filter’s result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes. This can be useful for making jq filters talk to non-JSON-based systems.
(Google翻訳)このオプションを使用すると、フィルターの結果が文字列の場合、引用符付きのJSON文字列としてフォーマットされるのではなく、標準出力に直接書き込まれます。 これは、jqフィルターが非JSONベースのシステムと通信するのに役立ちます。
最後を.[]
としないと以下のようになり、-r
オプションは働きません。
> cat hoge.json | jq -s -r '[ .[] | keys ] | flatten | unique'
[
"hoge1",
"hoge2",
"hoge3",
"hoge4",
"hoge5",
"hoge6"
]
jq
コマンドは奥が深いなぁ。
おまけ
Google翻訳さんによるとslurp
は丸lurみ
だそうですw
ヌードルハラスメント的ななにかが働いているのでしょうか???
参考
[jq] JSONデータの特定階層にあるキー名のユニーク値を取得 - Qiita
https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
jq Manual (development version)
https://stedolan.github.io/jq/manual/