JSON形式ごとにjq
コマンドでレコード件数をカウントする方法をまとめます。
はじめに
先日、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
コマンドなら柔軟に対応できるので、上手く活用していきたいところです。
[関連記事]