BioErrorLog Tech Blog

試行錯誤の記録

JSONのレコード件数をjqコマンドでカウントする | Linux shell

JSON形式ごとにjqコマンドでレコード件数をカウントする方法をまとめます。

はじめに

こんにちは、@bioerrorlogです。

先日、LinuxコマンドラインでJSONのレコード件数をカウントすることがありました。 csvファイルであれば行数をカウントすれば済みますが、JSONの場合は記述形式によってカウント方法を工夫する必要があります。

今回は、jqコマンドを用いたJSON形式ごとのレコード数カウント方法をまとめます。

環境

OS: Amazon Linux 2で動作を確認しています。

JSONのレコード件数をカウントする

3つのJSON形式のレコード件数カウント方法を見ていきます。

  • 配列括りのJSON Document
  • オブジェクト括りのJSON Document
  • JSON Lines

配列括りのJSON Document

# array.json
[
  {"id":1,"name":"aaa"},
  {"id":2,"name":"bbb"},
  {"id":3,"name":"ccc"},
  {"id":4,"name":"ddd"},
  {"id":5,"name":"eee"}
]

上記のような配列括りのJSONarray.jsonのレコード数をカウントするには、以下のコマンドを実行します。

cat array.json | jq 'length'
# 出力: 5

このコマンドではまず、catコマンドでJSONファイルの中身をパイプ|jqコマンドに渡します。
そしてjqコマンドではフィルタにlengthを適用し、レコード件数を取得します。

jqコマンドのビルトイン関数であるlengthは、渡された値の形式に応じて要素数を返します。 配列が渡された場合は、配列の要素数を返します。
jq manページ より:

length
  The builtin function length gets the length of various different types of value:
   ·  The length of a string is the number of Unicode codepoints it contains (which will be the same as its JSON-encoded length in bytes if it´s pure ASCII).
   ·  The length of an array is the number of elements.
   ·  The length of an object is the number of key-value pairs.
   ·  The length of null is zero.

オブジェクト括りのJSON Document

# object.json
{
  "records": [
    {"id":1,"name":"aaa"},
    {"id":2,"name":"bbb"},
    {"id":3,"name":"ccc"},
    {"id":4,"name":"ddd"},
    {"id":5,"name":"eee"}
  ]
}

上記のようなオブジェクト括りのJSONobject.jsonに対し、"records"に格納された配列内のレコード数をカウントするには、以下のコマンドを実行します。

cat objects.json | jq '.records | length'
# 出力: 5

このコマンドでは、jqコマンドのフィルタとして'.records | length'を適用しています。

まずフィルタ.recordsで"records"に格納された配列を取り出した後、lengthフィルタを適用することで配列の要素数がカウントできます。

JSON Lines

# lines.json
{"id":1,"name":"aaa"}
{"id":2,"name":"bbb"}
{"id":3,"name":"ccc"}
{"id":4,"name":"ddd"}
{"id":5,"name":"eee"}

上記のようなJSON Lines形式のファイルlines.jsonのレコード件数を取得するには、以下のコマンドを実行します。

cat lines.json | jq -s 'length'
# 出力: 5

まず、jqコマンドに-s/--slurpオプションを付与することで、以下のように入力全体が一つの配列に格納される形で出力されます。

$ cat lines.json | jq -s
[
  {
    "id": 1,
    "name": "aaa"
  },
  {
    "id": 2,
    "name": "bbb"
  },
  {
    "id": 3,
    "name": "ccc"
  },
  {
    "id": 4,
    "name": "ddd"
  },
  {
    "id": 5,
    "name": "eee"
  }
]

これに対してlengthフィルタを適用することで、レコード件数を取得することが出来ます。

※ ちなみに、例えばインプットファイルが以下のように適当に改行を含んでいても問題なく機能します。

# lines.json
{
  "id":1,
  "name":"aaa"}
{"id":2,"name":"bbb"}
{"id":3,
"name":"ccc"}
{
  "id":4,
  "name":"ddd"
}
{"id":5,"name":"eee"
}

レコード件数カウント:

cat lines.json | jq -s 'length'
# 出力: 5

おわりに

今回は、jqコマンドを用いてJSONのレコード件数をカウントする方法をまとめました。

JSONファイルは多様な記述方法があるので、何か処理を適用するときはインプットファイルの形式に注意する必要があります。

いずれのJSON形式でもjqコマンドなら柔軟に対応できるので、上手く活用していきたいところです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

参考

jq Manual (development version)

bash - How to count items in JSON object using command line? - Stack Overflow

JSON Lines

JSON Schema: A Media Type for Describing JSON Documents

JSON - Wikipedia