1. kai_kou

    Posted

    kai_kou
Changes in title
+jqコマンドでJSONからキー名をいい感じに取得する
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,160 @@
+下記記事を参考にほぼほぼやりたいことはできたのですが、ハマったのでメモ。
+
+[jq] JSONデータの特定階層にあるキー名のユニーク値を取得 - Qiita
+https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
+
+
+## JSONファイル
+
+行ごとにキーが同じだったり、違ったり、数も違うちょっと困ったJSONファイルがあるときに使えます。
+
+```json:hoge.json
+{"hoge1": "hoge", "hoge2": 2, "hoge3": false}
+{"hoge2": "hoge", "hoge3": 2, "hoge4": false, "hoge5": "FOO"}
+{"hoge1": "hoge", "hoge2": 2, "hoge6": false}
+```
+
+## いい感じのコマンド
+
+```console
+> 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回だけ実行します。
+
+
+```console
+# -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` が効きません。
+
+```console
+> 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` オプションは働きません。
+
+```console
+> cat hoge.json | jq -s -r '[ .[] | keys ] | flatten | unique'
+
+[
+ "hoge1",
+ "hoge2",
+ "hoge3",
+ "hoge4",
+ "hoge5",
+ "hoge6"
+]
+```
+
+`jq` コマンドは奥が深いなぁ。
+
+
+## おまけ
+
+Google翻訳さんによると`slurp` は`丸lurみ` だそうですw
+ヌードルハラスメント的ななにかが働いているのでしょうか???
+
+<img width="1330" alt="スクリーンショット 2019-11-27 16.32.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/4e69e374-1edd-75a9-76ba-3c7b73fb8300.png">
+
+
+## 参考
+
+[jq] JSONデータの特定階層にあるキー名のユニーク値を取得 - Qiita
+https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
+
+jq Manual (development version)
+https://stedolan.github.io/jq/manual/
+