mattintosh note

技術書典に出たい人生だった…

jq コマンドで2つのファイルから配列を結合する

YouTube Data API を使っていると maxResult=50 が限界なのでそれ以上になるとどうしても JSON が分かれてしまう。Python とかなら JSON をオブジェクトに変換してしまえばいいのだけど、忘れるので jq コマンドで実行する方法をメモっておく。

1.json

{
  "items": [
    {
      "id": "UCD8HOxPs4Xvsm8H0ZxXGiBw",
      "snippet": {
        "title": "Mel Channel 夜空メルチャンネル",
        "publishedAt": "2018-04-25T02:07:54.000Z",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mC5-XNF0MJc4spIJdwfxY1sFIyjWB8qAHd9_A=s88-mo-c-c0xffffffff-rj-k-no",
            "width": 88,
            "height": 88
          },
          "medium": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mC5-XNF0MJc4spIJdwfxY1sFIyjWB8qAHd9_A=s240-mo-c-c0xffffffff-rj-k-no",
            "width": 240,
            "height": 240
          },
          "high": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mC5-XNF0MJc4spIJdwfxY1sFIyjWB8qAHd9_A=s800-mo-c-c0xffffffff-rj-k-no",
            "width": 800,
            "height": 800
          }
        }
      },
      "contentDetails": {
        "relatedPlaylists": {
          "uploads": "UUD8HOxPs4Xvsm8H0ZxXGiBw"
        }
      },
      "statistics": {
        "viewCount": "1217525",
        "subscriberCount": "32661"
      }
    }
  ]
}

2.json

{
  "items": [
    {
      "id": "UCsg-YqdqQ-KFF0LNk23BY4A",
      "snippet": {
        "title": "樋口楓【にじさんじ所属】",
        "publishedAt": "2018-01-31T10:47:47.000Z",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mCLW7sO_ERKAC41K1XInz_nT0r8Q7JHgGnV0w=s88-mo-c-c0xffffffff-rj-k-no",
            "width": 88,
            "height": 88
          },
          "medium": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mCLW7sO_ERKAC41K1XInz_nT0r8Q7JHgGnV0w=s240-mo-c-c0xffffffff-rj-k-no",
            "width": 240,
            "height": 240
          },
          "high": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mCLW7sO_ERKAC41K1XInz_nT0r8Q7JHgGnV0w=s800-mo-c-c0xffffffff-rj-k-no",
            "width": 800,
            "height": 800
          }
        }
      },
      "contentDetails": {
        "relatedPlaylists": {
          "uploads": "UUsg-YqdqQ-KFF0LNk23BY4A"
        }
      },
      "statistics": {
        "viewCount": "13124038",
        "subscriberCount": "172943"
      }
    }
  ]
}

トップレベルのオブジェクトが2つある場合はそれぞれ .[0].[1] のようなインデックスに入っているらしい。そこから配列部分を取り出して + で連結してあげる。あとは並び替えの条件とかを追加して最後にまた {"items": .} に入れてあげる。

メモ: 配列からピンポイントで .[0] のように取ろうとすると要素が1つの場合は配列にしてくれないようなので .[0:1] のようにスライスで取得する。

cat 1.json 2.json | jq -s '.[0].items + .[1].items | sort_by(.statistics.viewCount | tonumber) | reverse | {"items": .}'

concatenated.json

{
  "items": [
    {
      "id": "UCsg-YqdqQ-KFF0LNk23BY4A",
      "snippet": {
        "title": "樋口楓【にじさんじ所属】",
        "publishedAt": "2018-01-31T10:47:47.000Z",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mCLW7sO_ERKAC41K1XInz_nT0r8Q7JHgGnV0w=s88-mo-c-c0xffffffff-rj-k-no",
            "width": 88,
            "height": 88
          },
          "medium": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mCLW7sO_ERKAC41K1XInz_nT0r8Q7JHgGnV0w=s240-mo-c-c0xffffffff-rj-k-no",
            "width": 240,
            "height": 240
          },
          "high": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mCLW7sO_ERKAC41K1XInz_nT0r8Q7JHgGnV0w=s800-mo-c-c0xffffffff-rj-k-no",
            "width": 800,
            "height": 800
          }
        }
      },
      "contentDetails": {
        "relatedPlaylists": {
          "uploads": "UUsg-YqdqQ-KFF0LNk23BY4A"
        }
      },
      "statistics": {
        "viewCount": "13124038",
        "subscriberCount": "172943"
      }
    },
    {
      "id": "UCD8HOxPs4Xvsm8H0ZxXGiBw",
      "snippet": {
        "title": "Mel Channel 夜空メルチャンネル",
        "publishedAt": "2018-04-25T02:07:54.000Z",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mC5-XNF0MJc4spIJdwfxY1sFIyjWB8qAHd9_A=s88-mo-c-c0xffffffff-rj-k-no",
            "width": 88,
            "height": 88
          },
          "medium": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mC5-XNF0MJc4spIJdwfxY1sFIyjWB8qAHd9_A=s240-mo-c-c0xffffffff-rj-k-no",
            "width": 240,
            "height": 240
          },
          "high": {
            "url": "https://yt3.ggpht.com/a-/AAuE7mC5-XNF0MJc4spIJdwfxY1sFIyjWB8qAHd9_A=s800-mo-c-c0xffffffff-rj-k-no",
            "width": 800,
            "height": 800
          }
        }
      },
      "contentDetails": {
        "relatedPlaylists": {
          "uploads": "UUD8HOxPs4Xvsm8H0ZxXGiBw"
        }
      },
      "statistics": {
        "viewCount": "1217525",
        "subscriberCount": "32661"
      }
    }
  ]
}