パラボラアンテナと星の日記

あることないこと

複数カラムでjoin(1)したい

join便利

joinコマンド便利です。使い方はこちらのサイトが良くわかりやすかったです。

joinコマンドが便利過ぎて生きるのが辛い - Web就活日記

複数カラムでjoinしたい

さて、joinの列指定オプション(-1,-2)は、複数カラムを指定できないように見えます。
複数カラム指定できるように再発明してみます。

こんなデータを用意。

$ cat AA.txt
AA 1 100円
AA 2 100円
BB 1 300円
BB 2 300円
CC 4 200円
DD  400円
EE 1 500円
$ cat BB.txt
labelA AA 1 Category1
labelB BB 1 Category2
labelC CC 4 Category3
labelD DD 5 Category4

こんな感じで使います

$ multiple-columns-join -1 1 -1 2 -2 2 -2 3 AA.txt BB.txt
AA 1 100円 labelA AA 1 Category1
BB 1 300円 labelB BB 1 Category2
CC 4 200円 labelC CC 4 Category3

できてそうです。本家のjoinは結合列は出力されないのですが、
このmultiple-columns-joinでは結合列も出力しています。

コードはこんな感じです
githubにも上げました


hoshinotsuyoshi/multiple-columns-join · GitHub

#!/usr/bin/ruby
require 'optparse'
opt = OptionParser.new

_1 = []
_2 = []
opt.on('-1 [VAL]') {|v| _1 << v }
opt.on('-2 [VAL]') {|v| _2 << v }
opt.parse!(ARGV)

_1.map!{|v| v.to_i - 1}
_2.map!{|v| v.to_i - 1}

enum1 = File.open(ARGV[0], 'r').each
enum2 = File.open(ARGV[1], 'r').each

loop do
  a1 = enum1.peek.split(' ').values_at(*_1)
  a2 = enum2.peek.split(' ').values_at(*_2)

  case a1 <=> a2
  when -1
    then enum1.next
  when 0
    then puts [enum1.next.chomp, enum2.next.chomp].join(' ')
  when 1
    then enum2.next
  end
end

問題

問題としては

  • sort済みでないといけない(joinもそうなのですが)
  • joinする列でuniqueでないといけない(joinはそうではありません)
  • デリミタが指定できない
  • 終了コードを気にしていない

とかがある点に注意です