はじめに
複数のデータベースやシステムにデータがまたいでいるとき、それらのデータをidかなにかで結合したいときがあります。
自分のlocalにDBいれて、とりこんでしまえばSQLで結合するのは難しくないです。
そこまでするほどでないとか、DBに取り込むにはデータが多すぎるときは、シェルでさくっとやりたいことがあります。
joinコマンドのバージョン
次のもの以降なら問題ないと思います。古いバージョンだと、一部使えない機能があります。
$ join --version
join (GNU coreutils) 8.32
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Mike Haertel.
内部結合(inner join)
ヘッダーありの場合は--header
オプションをつけます。
区切り文字は-t
でいけます。 csvなら-t,
でいけます。tsvの場合はタブ文字を認識させるために、-t $'\t'
とします。
ファイルの例としては、tsvで、ダブルクォートを囲み文字のものとします
$ cat test1.tsv
"id" "name"
"1" "test 1"
"2" "test 2"
"3" "test 3"
"4" "test 4"
$ cat sample.tsv
"id" "tel"
"2" "031234567"
"4" "123456789"
$ join --header -t $'\t' test1.tsv sample.tsv
"id" "name" "tel"
"2" "test 2" "031234567"
"4" "test 4" "123456789"
左外部結合(left join)
-a
オプションで、マッチしないものも残すファイルを指定します。
左側を残した場合は-a 1
になります。
$ join --header -t $'\t' -a 1 test1.tsv sample.tsv
"id" "name" "tel"
"1" "test 1"
"2" "test 2" "031234567"
"3" "test 3"
"4" "test 4" "123456789"
これだと、マッチしなかった行について、右側のファイルにあるカラムがかけてしまいます。
そのときは、-o
オプションと一緒に、-e
オプションを使うことで指定できます。
とくになければ -o auto
をするのが便利です。両方のファイルのカラムがすべてでます。
(古いバージョンだと、これが使えないので注意)
$ join --header -t $'\t' -a 1 -o auto -e '""' test1.tsv sample.tsv
"id" "name" "tel"
"1" "test 1" ""
"2" "test 2" "031234567"
"3" "test 3" ""
"4" "test 4" "123456789"
cross join
あまり使う場面がなさそうですが、両方のファイルのidを残したい場合があります。
いわゆるcross join相当をしたいときです。
-a 1 -a 2
でできます。
$ cat sample2.tsv
"id" "tel"
"2" "031234567"
"4" "123456789"
"5" "050XXXXYYYY"
"6" "06XXXXYYYY"
$ join --header -t $'\t' -a 1 -a 2 -o auto -e '""' test1.tsv sample2.tsv
"id" "name" "tel"
"1" "test 1" ""
"2" "test 2" "031234567"
"3" "test 3" ""
"4" "test 4" "123456789"
"5" "" "050XXXXYYYY"
"6" "" "06XXXXYYYY"
除外処理
除外したいIDのリストをファイルでもっていて、IDがその除外リスト以外のものだけを抽出したいケースがあります。
-vオプションで残したいファイルの方を指定するだけです。
"id"
"2"
"3"
$ join --header -t $'\t' -v 1 test1.tsv exclude.tsv
"id" "name"
"1" "test 1"
"4" "test 4"
参考リンク
- https://yut.hatenablog.com/entry/20120907/1346975281
- https://qiita.com/motthy/items/c2c445417b677b56ac67
- https://orebibou.com/2017/07/join%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E8%A6%9A%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8F%E3%81%A8%E4%BE%BF%E5%88%A9%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B98%E5%80%8B/
- https://qiita.com/doitnow420@github/items/88fa7878282866443803
- https://stackoverflow.com/questions/1722353/unix-join-separator-char