大きな json の中身を jq コマンドで探検してみる

# 解決したい課題

json の構造についてのドキュメントがない状態で、巨大な json ファイルの中身を調べたい!だけどあまりにも巨大なファイルなので、途方にくれている

こういった場合、みなさんはどのように調べますでしょうか

GUI のツールを使うのもありですが、コマンドラインでパースした結果を別のコマンドに渡したい場合、それだとやりにくかったりしますね。

# 解決策

## jq コマンドを利用する

例： [AWS の IP 一覧](https://ip-ranges.amazonaws.com/ip-ranges.json) があります。これを探検してみましょう。

jq コマンドには多数の機能が用意されています。

単純に jq コマンドに渡すだけだと、まあ以下のように長ーい結果が帰ってきます

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq 
{
  "syncToken": "1581352989",
  "createDate": "2020-02-10-16-43-09",
  "prefixes": [
    {
      "ip_prefix": "13.248.118.0/24",
      "region": "eu-west-1",
      "service": "AMAZON"
    },
    {
      "ip_prefix": "18.208.0.0/13",
      "region": "us-east-1",
      "service": "AMAZON"
    },
    {
      "ip_prefix": "52.95.245.0/24",
      "region": "us-east-1",
      "service": "AMAZON"
    },
    {
... snip ...

```

行数も 12923 行

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq |wc -l
   12923
```

まず、自分の場合は keys という機能を使います。
これを使うことで、大枠の構造がわかります。

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq keys
[
  "createDate",
  "ipv6_prefixes",
  "prefixes",
  "syncToken"
]
```

4つのオブジェクトのキーが最初の構成で使われているようです

createDate が何なのか見てみましょう
キー名の先頭にドットをつけて 検索します。

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq .createDate
"2020-02-10-16-43-09"
```

2020-02-10-16-43-09 という文字列が返ってきました。文字列が返ってきました。ここについてはこれ以上の階層ではないようです。

では ipv6_prefixes を見てみましょう

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq .ipv6_prefixes
[
  {
    "ipv6_prefix": "2a05:d07c:2000::/40",
    "region": "eu-west-3",
    "service": "AMAZON"
  },
  {
    "ipv6_prefix": "2600:9000:a300::/40",
    "region": "GLOBAL",
    "service": "AMAZON"
  },
  {
    "ipv6_prefix": "2a05:d000:8000::/40",
    "region": "eu-west-1",
    "service": "AMAZON"
  },
  {
    "ipv6_prefix": "2406:dafe:2000::/40",
    "region": "ap-northeast-2",
    "service": "AMAZON"
... snip ...


$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq .ipv6_prefixes|wc -l
    2802
```

2802 行もあるようです。かなりの数が返ってきました。
構造をみてみましょう。 `".ipv6_prefixes|keys"` のようにキーの後ろにパイプをつけて keys をつければOKです

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq ".ipv6_prefixes|keys"|head -10
[
  0,
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,

```

0 から始まる数字のキーが返ってきました。配列のようです。
配列の中の構造も更に見てみましょう。仮うちで 0 の配列の中身を見てみます


```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq ".ipv6_prefixes[0]|keys"
[
  "ipv6_prefix",
  "region",
  "service"
]
```

こうすることで、配列の中身は3つのキーが含まれるオブジェクトであることがわかりました
さらに 調べてみましょう。

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq ".ipv6_prefixes[0].ipv6_prefix | keys"
jq: error (at <stdin>:12922): string ("2a05:d07c:...) has no keys
```

文字列なのでキーはないよと怒られました。
他のキーを調べてみても同様なので、keys をはずしてみました

```
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq ".ipv6_prefixes[0]"
{
  "ipv6_prefix": "2a05:d07c:2000::/40",
  "region": "eu-west-3",
  "service": "AMAZON"
}

```

こうすることで、巨大な json であっても、必要な情報にたどり着くことができます

といろいろ書きましたが、この json はちゃんとドキュメントが書かれているので、そういう場合はドキュメント見るとよいですｗ

https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-ip-ranges.html#aws-ip-syntax


ただ、開発でデバッグする際に何か json の構造がおかしい場合に知っておいて損はないかと思います。