JSONファイルを扱うのに便利なjqコマンドで、unique_byを複数対応するやり方

2019年3月1日

jq テクノロジー プログラミング

アプリケーションやITのシステムはプログラムの出来不出来でクオリティが決まると思っているのは非常に素人考えで、実は重要なのがデータ部分であることは、経験者なら誰もが同じことを口にするでしょう。 僕の経験では、世の中のITシステムトラブルの多くを占めているのはデータベース障害であるという事実も、エンジニアを仕事にしている人であれば、頷いてくれる内容です。 データベース障害を除きたければデータベースアプリケーションを使わなければいいんです! という事で、jsonファイルをjqコマンドで直接使ってシステムを作り、オレオレデータベースを構築してSQL障害から開放された僕ですが、jqコマンドが非常に便利すぎて、Linuxで正規モジュールに採用してくれないかと切に願っております。 そんなjqコマンドを使っていて、あまり他の解説サイトやブログで書かれていない内容があったので、小さなトピックですが、備忘録として書いておきます。

ユニークIDが複数ある場合のunique_by命令の書き方

まずは、テストデータは以下のjsonデータを使います。 {"id1":1,"id2":"a","val":"aaa"} {"id1":1,"id2":"b","val":"bbb"} {"id1":1,"id2":"a","val":"ccc"} {"id1":2,"id2":"b","val":"ddd"} {"id1":2,"id2":"a","val":"eee"} {"id1":2,"id2":"b","val":"fff"} {"id1":3,"id2":"a","val":"ggg"} {"id1":3,"id2":"b","val":"hhh"} {"id1":3,"id2":"a","val":"iii"} {"id1":4,"id2":"b","val":"jjj"} これを"id1"のkey値でユニーク値を取得するには、 jq --slurp --compact-output 'unique_by(.id1) | .[]' sample.json {"id1":1,"id2":"a","val":"aaa"} {"id1":2,"id2":"b","val":"ddd"} {"id1":3,"id2":"a","val":"ggg"} {"id1":4,"id2":"b","val":"jjj"} ユニークデータを後書き有効にする場合は、 jq --slurp --compact-output 'reverse | unique_by(.id1) | .[]' sample.json 先頭に"reverse"をつけるだけでいいんです。 {"id1":1,"id2":"a","val":"ccc"} {"id1":2,"id2":"b","val":"fff"} {"id1":3,"id2":"a","val":"iii"} {"id1":4,"id2":"b","val":"jjj"} さらにid2も含めたユニークにしたい場合は、 jq --slurp --compact-output 'reverse | unique_by(.id1,.id2) | .[]' sample.json {"id1":1,"id2":"a","val":"ccc"} {"id1":1,"id2":"b","val":"bbb"} {"id1":2,"id2":"a","val":"eee"} {"id1":2,"id2":"b","val":"fff"} {"id1":3,"id2":"a","val":"iii"} {"id1":3,"id2":"b","val":"hhh"} {"id1":4,"id2":"b","val":"jjj"} いかがでしょうか?複数keyでのユニーク化が簡単にできました。 しかも、後書き有効なので、追記型のログデータなどで活用することが可能になります。

押さえておきたいポイント

今回のポイントは、unique_by(path_exp)命令の中の"path_exp"の部分でコントロールするだけという事に気がついた人も多いと思います。 ここを極めれば、データ抽出はかなり柔軟にできるようになります。 今回の複数対象にしたい場合は、,(カンマ)区切りで書けばOKです。 ちなみに、順番もポイントで、以下のように入れ替えると結果も変わります。 jq --slurp --compact-output 'reverse | unique_by(.id2,.id1) | .[]' sample.json {"id1":1,"id2":"a","val":"ccc"} {"id1":2,"id2":"a","val":"eee"} {"id1":3,"id2":"a","val":"iii"} {"id1":1,"id2":"b","val":"bbb"} {"id1":2,"id2":"b","val":"fff"} {"id1":3,"id2":"b","val":"hhh"} {"id1":4,"id2":"b","val":"jjj"} 書き込んだ順にソートされるようですが、抽出されるデータ自体は変わらないようですね。 この後でsort_byをしてもいいですが、unique_byの結果で一旦ソートがかかっているので、処理速度を早くしたければ、ここで一発で行うのがオススメです。 SQLだとSELECT文で同じことは出来るんですが、これらの相互コンバートできるプログラム作ったら便利そうだな・・・

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ