joinコマンド

あれ、メモし忘れてるかな? よく使い方を忘れるのでメモ。

関係データベースのjoinと同様の操作のコマンドがjoinコマンド。 CSVのように、決まったデリミタでフィールドが分けられている2つの ファイル(それを表とみなす)から、同じ(eq)なフィールドどうしを 結合し、必要なフィールドを組み合わせて出力するコマンド。 いえーい、文にするとややこしい。

たとえば、fooというファイルにユーザ名とローマ字氏名一覧があり、 barというファイルにpasswdファイルの元形式があるのだが、gecos部分は ダミーでつけた偽の名前になっているとする。

foo:

user01,YAMADA Taro
user02,TANAKA Hanako
user03,TAKAHASHI Makoto
user04,KIMURA Shoko

bar:

user01:*:10001:100:User 01:/home/user01:/bin/zsh
user02:*:10002:100:User 02:/home/user02:/bin/zsh
user03:*:10003:100:User 03:/home/user03:/bin/zsh
user04:*:10004:100:User 04:/home/user04:/bin/zsh

こんなとき、fooとbarの第1フィールドどうしをjoinし、

user01:*:10001:100:YAMADA Taro:/home/user01:/bin/zsh
  :

みたいな出力、つまり、:で区切られた7つのフィールドを

barの第1フィールド (fooのでもOK)
barの第2フィールド
barの第3フィールド
barの第4フィールド
fooの第2フィールド
barの第6フィールド
barの第7フィールド

を組み合わせて作りたいとしたら、joinを使って以下のようにする。

% sed 's/,/:/' foo | \
    join -t : -1 1 -2 1 -o 2.1,2.2,2.3,2.4,1.2,2.6,2.7 \
    - bar

フィールドのデリミタを揃える必要があるので、最初にfooの デリミタを , から : に直し、それをjoinコマンドに送り込み、 第1の表として - で渡している。-1オプションは第1の表の joinキーとなるフィールド番号、-2オプションは第2の表のそれ。 -oは見てなんとなく分かるじゃ呂。

ただし、両ファイルともjoinキーとなるフィールドでソートしてある必要が ある。もしfooの方が第1フィールドでソートされていなければ、sortコマンドを 挟んで、

% sed 's/,/:/' foo | sort -t: -k 1 | \
    join -t : -1 1 -2 1 -o 2.1,2.2,2.3,2.4,1.2,2.6,2.7 \
    - bar

みたいにすりゃよし。


叱咤激励感想ツッコミはゲストブック

Generated with mkdiary.rb
yuuji@example.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]