Rubyからagrepコマンドを叩くぜ!

grepは速い。

「100万件ぐらいの検索なら、シェルだけでも1000分の数秒でできます」。こう豪語するのは「パイプの匠」として紹介されたUSP研究所の當仲寛哲氏だ。

システム統合にSOA? RDBMS? bashで十分! − @IT

余談だが、無印良品の情報システムは、bashで作られているんだぜ!

なぜ速いか。

最近、トライ木(trie tree)というデータ構造を使っていたのだが、本当に必要なのか? と思えてきた。データサイズにもよるだろうが、grepで何も問題なさそう。grepには、agrepという曖昧検索に対応したものもあるし*1

それに何より、grepが使えないサーバの方が少なさそう。気軽に使える最強の検索システム!!

ということで、トライ木を捨てて、agrepのRubyクラスを作った。動いているのでよしとする。

#!/usr/bin/ruby

class Agrep

  def initialize(file_name, option = {})
    @@agrep_path = option[:agrep_path] ? option[:agrep_path] : which
    @@target = file_name
  end
  
  def which
    %x{which agrep}.chomp
  end
  
  def command(pattern)
    @@agrep_path + " -B -y -e '#{pattern}' #{@@target}"
  end
  
  def search(pattern)
    IO.popen(command(pattern)) do |io|
      io.to_a
    end
  end

end

a = Agrep.new("./address2.txt")
a.search("博多").each {|i| puts i }

げげげ。単一ファイルしか対応してないじゃん。

ちなみに、TextMateでコマンド+rを押しても、agrepなんてコマンドがありませんと言わる。そのため、ターミナルから実行させる必要がある。

*1:本棚.orgは、agrep使っているみたい