csvファイルのある列をキーにjoinしたいときってありますよね?
データベース使えばすぐなんだけど,ファイルだけでできないのかなーと思って調べたところ join コマンドが便利そうだったのでメモです.
元ファイル
こんな感じのファイルがあるとします.2つのファイルを結合して加工したいときってありますよね!!!!
100,a
200,b
400,c
200,x
300,y
500,z
join コマンド!!!
内部結合(INNER JOIN)
$ join -t, a.txt b.txt
200,b,x
(明示的にした場合)
$ join -t, -1 1 -2 1 -o 0 1.2 2.2 a.txt b.txt
200,b,x
-t
は,デリミタ(区切り文字)です.-1, -2
は結合の条件で,SQLでいう INNER JOIN ON 〜
の条件式にあたります.-1
は,a.txt でキーとする列,-2
はb.txtでキーとする列です.
-o
は出力する列番号を指定します.1.2
は1つ目のファイル(a.txt)の2列目を表示せよという意味になります.0
を指定するとjoin条件としたキーを表示します.
外部結合(LEFT OUTER JOIN)
内部結合できるなら外部結合ももちろんできます.
$ join -t, -a 1 -1 1 -2 1 -o 0 1.2 2.2 -e 'NULL' a.txt b.txt
100,a,NULL
200,b,x
400,c,NULL
-a
は -1, -2
でマッチしなかった行も表示させよという意味になります.-a
のあとにはファイル番号を指定することになります.
具体的には -a 1
だと左外部結合(LEFT OUTER JOIN),-a 2
だと右外部結合(RIGHT OUTER JOIN)になります.
完全外部結合(FULL OUTER JOIN)
滅多に使うことないけど,使いたくなるよねー.ということで,これは -a
を2つとも指定することでできます.
$ join -t, -a 1 -a 2 -1 1 -2 1 -o 0 1.2 2.2 -e "NULL" a.txt b.txt
100,a,NULL
200,b,x
300,NULL,y
400,c,NULL
500,NULL,z
交差結合(CROSS JOIN)
互いのファイルのすべての行の組み合わせですね.
ちょっと試そうとしたんですが,すぐにでてこなかったので今回は省略.どなたか教えて偉い人!
さいごに
シンプルな結合ならRDBMSなんていらなかったんや!