zipgrep.rb

#!/usr/bin/ruby -Ks
# -*- coding: shift_jis -*-
P={#[Prefectures]
'0'=>'愛知県',
#..snip..
'wc'=>'z邑智郡邑南町'
}
def get_prefs(firstChar)
  open(firstChar) do |f|
    cities = []
    f.each do |l|
      a = l.split(/,/)
      cities << a[1]
    end
    prefs = []
    cities.uniq.each do |s|
      prefs << P[s][0,1]
    end
    prefs.uniq.sort.inject([]){|r,n|r<<P[n]}
  end
end
if ARGV.size <= 0
  puts "Usage : zipgrep code"
  10.times do |i|
    print "#{i} : " + get_prefs(i.to_s).join(",")+"\n"
  end
  exit
end
code = ARGV[0].dup
code.sub!(/^./,'')
firstChar = $&
if code.size == 0
  puts get_prefs(firstChar).join(",")
else
  open(firstChar) do |f|
    f.each do |l|
      if l[0,code.size] == code
        a = l.split(',')
        city = P[a[1]]
        printf "%s%s %s %s", firstChar, a[0], city.sub(/./){P[$&]+' '}, a[2]
      end
    end
  end
end

郵便番号ファイルを先頭の数字で分割した後、地名をテーブル化してgrepできる様にした。

出力結果:

$ time zipgrep.rb 1000
1000000 東京都 千代田区 以下に掲載がない場合
1000001 東京都 千代田区 千代田
1000002 東京都 千代田区 皇居外苑
1000003 東京都 千代田区 一ツ橋(1丁目)
1000004 東京都 千代田区 大手町(次のビルを除く)
1000005 東京都 千代田区 丸の内(次のビルを除く)
1000006 東京都 千代田区 有楽町
1000011 東京都 千代田区 内幸町
1000012 東京都 千代田区 日比谷公園
1000013 東京都 千代田区 霞が関(次のビルを除く)
1000014 東京都 千代田区 永田町(次のビルを除く)
1000100 東京都 大島町 以下に掲載がない場合
1000101 東京都 大島町 元町
1000102 東京都 大島町 岡田
1000103 東京都 大島町 泉津
1000104 東京都 大島町 野増
1000211 東京都 大島町 差木地
1000212 東京都 大島町 波浮港
1000301 東京都 利島村 利島村一円
1000400 東京都 新島村 以下に掲載がない場合
1000401 東京都 新島村 若郷
1000402 東京都 新島村 本村
1000511 東京都 新島村 式根島
1000601 東京都 神津島村 神津島村一円

real    0m0.182s
user    0m0.046s
sys     0m0.061s

0.2秒くらいで検索できる。単なるgrepよりは早い。

$ time grep '"1000' ken_all.csv 
13101,"100  ","1000000","トウキョウト","チヨダク","イカニケイサイガナイバアイ","東京都","千代田区","以下に掲載がない場合",0,0,0,0,0,0
(略)

real    0m1.539s
user    0m0.046s
sys     0m0.078s