Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@kai_kou

jqコマンドでJSONからキー名をいい感じに取得する

下記記事を参考にほぼほぼやりたいことはできたのですが、ハマったのでメモ。

[jq] JSONデータの特定階層にあるキー名のユニーク値を取得 - Qiita
https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0

JSONファイル

行ごとにキーが同じだったり、違ったり、数も違うちょっと困ったJSONファイルがあるときに使えます。

hoge.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
ヌードルハラスメント的ななにかが働いているのでしょうか???

スクリーンショット 2019-11-27 16.32.36.png

参考

[jq] JSONデータの特定階層にあるキー名のユニーク値を取得 - Qiita
https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0

jq Manual (development version)
https://stedolan.github.io/jq/manual/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
8
Help us understand the problem. What are the problem?