LoginSignup
12
5

More than 5 years have passed since last update.

JOINコマンドを使う際の注意

Last updated at Posted at 2017-05-19

はじめに

集計はRDBばかりに頑張らせるのをやめると幸せになれる。のですが、JOINコマンドを利用するともっと幸せになれます。

JOINコマンドとは

こちらに詳しくまとまっているのですが、2つのtsvファイルや、csvファイルをjoinする事ができます。

RDBを利用できない時に、ファイルだけでテーブル間の結合処理ができるという夢のようなコマンドですが、sortとの兼ね合いで思ったようにjoin出来ないことがあります。

結論から言うと

join: [ファイル]: is not sorted: 

というエラーが出たときには、

  • join前のsort時にLANG=Cを指定する。
  • join時にもLANG=Cを指定する。

JOINが失敗するなら、grepで似たようなこと出来ないの?

近いことで、以下のコマンドで、[ファイル2]中にある[ファイル1]の内容を含む行を抽出することができますが、これは計算量のオーダーが[ファイル1のサイズ] * [ファイル2のサイズ]であるため、これが巨大なときには何時まで待っても完了しません。

grep -f [ファイル1] [ファイル2] 

ファイル1が100万行,ファイル2が1000万行だったときには計算量のオーダーは10兆回です。

JOINコマンドは速い

JOINコマンドを利用するためには、予め[ファイル1]と[ファイル2]が適切にソートされている必要がありますが、その分高速に動作します。
ソート済みのファイル同士を上から比較することで、[ファイル1のサイズ]+[ファイル2のサイズ]のオーダーの計算量で比較を行ないます。

ファイル1が100万行,ファイル2が1000万行だったときには計算量のオーダーは1100万回で、grepを利用するケースのおよそ91万分の1です。

sort [ファイル1] > [ソート済みファイル1]
sort [ファイル2] > [ソート済みファイル2]

SORTの際に気をつけなければならないこと

sortコマンドは環境変数により、文字列のスコア評価が変わり、ソート順が変更されてしまいます。

例:
* 大文字小文字を無視する。
* 数値以外を無視する。
* "-"ハイフンや"+"プラスなどを無視する
* etc...

sort時の文字列スコア評価とjoin時の文字列スコア評価が異なるとjoinコマンドは

join: [ファイル1]: is not sorted:

というエラーを吐き、処理を中断してしまいます。

ここで、sortの結果を固定するために、LANG=Cを指定して下さい。

LANG=C sort [ファイル1] > [ソート済みファイル1]
LANG=C sort [ファイル2] > [ソート済みファイル2]

JOINの際に気をつけなければならないこと

sortと同様に、joinコマンドも環境変数により文字列のスコア評価が変わりますので、環境によってはこちらも適切に指定してあげないとjoin出来ません。
sort時に指定したのと同じLANGを指定してjoinします。

LANG=C join [ソート済みファイル1] [ソート済みファイル2] [オプション]
12
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
5