みなさん、SQLは得意ですか?私は苦手です。が、ちょっと面白そうなツールを見つけたので紹介します。
SQLを使ってJSON、CSV、Excelなどからデータを抽出できます。JSONやCSVのパースならyqコマンドでも十分そうですが、SQLで抽出できるということで、ちょっと興味が湧きました。
インストール
https://github.com/multiprocessio/dsq#install
macOSならHomebrewを使うのが簡単そうです。ビルド済みのバイナリもReleasesにありますので、公式の手順に従ってインストールをします。
使ってみる
まずは仮のデータが必要ですね。私はリポジトリに入っているテストデータを使用しました。
https://github.com/multiprocessio/dsq/tree/main/testdata
1つずつダウンロードするも面倒なのでcloneしてしまいます。
$ git clone https://github.com/multiprocessio/dsq.git $ cd dsq/testdata
使い方は簡単です。dsqの引数でファイルを渡すか、stdinから文字列を渡してあげるといいようです。
$ dsq /path/to/file QUERY or $ cat /path/to/file | dsq -s file-type QUERY
stdinから受け取るときは、-sにMIME Typeを指定する必要があるそうです。サポートされてるMIMEは以下。
https://github.com/multiprocessio/dsq#supported-data-types
今回は前者の引数にファイルを指定する方法で進めていきます。
QUERYの書き方は至って普通ですね。テーブル名のところが{}になるところが違うくらいでしょうか。
basic_logs.csvからnameだけを抽出してみます。
$ dsq basic_logs.csv 'select name from {}'
[{"name":"phil"},
{"name":"buddy"}]
nameだけ取得できています。結果はJSONで帰ってくるみたいですね。整形するには--prettyオプションを使います。
$ dsq --pretty basic_logs.csv 'select name from {}'
+-------+
| name |
+-------+
| phil |
| buddy |
+-------+
生のデータが欲しい時は、jqでさらに絞り込んであげる必要がありました。
$ dsq basic_logs.csv 'select name from {}' | jq -r '.[].name'
phil
buddy
複数のファイルを扱うこともできるようです。テーブル名に{}を入れていたのですが、これは暗黙的に{0}という意味みたいです。この0はインデックスで、何個目のファイルっというを表しています。複数のファイルを扱う時は{0}で1つ目、{1}で2つ目のファイルを指定します。JOIN的なあれです。
$ dsq join/users.csv join/ages.json 'select u.name, a.age from {0} u join {1} a on u.id = a.id'
[{"name":"Ted","age":88},
{"name":"Marjory","age":56},
{"name":"Micah","age":33}]
users.csvにあるidとages.jsonにあるidから名前と年齢で結合できています。
最後はエクセル…はたして……
$ dsq userdata.xlsx 'select `Phone Number ` from {} limit 1'
[{"Phone Number ":"(804) 896-6245 x269"}]
ちゃんとエクセルデータから抽出もできました。すごい
まとめ
SQLは苦手ですが、JSONやCSVからちょっとしたクエリでデータを抽出できるのはいいですね。JOINは使えるのはわかったんですが、私には使い道が思いつきませんでした。何か便利な使い方を思いついた方はこっそりどこかで教えてください。