[を]インデックスを使った指定行取り出しプログラム(Pure Perl)をRubyで書き換えてみました。
頭から操作する方法
まずはファイルの頭から操作していくナイーブな方法
コード(getline-naive.rb)
#!/usr/bin/env ruby qidx = ARGV.shift.to_i # start from 0 tgtfn = ARGV.shift f = open(tgtfn) while line = f.gets next if $. != qidx + 1 print line break end f.close
実行例:
$ cat test.dic Japan Tokyo Yokohama This is a pen Hello World $ ./getline-naive.rb 2 test.dic Yokohama
インデックスを使う方法
インデックスを作成するプログラム。
コード(mkidx.rb):
#!/usr/bin/env ruby ip = 0 while line = gets print [ip].pack("N") ip += line.length end
実行例:
$ ./mkidx.rb test.dic > test.dic.ary $ od -t x1 test.dic.ary 0000000 00 00 00 00 00 00 00 06 00 00 00 0c 00 00 00 15 0000020 00 00 00 23 0000024
インデックスを使った指定行取り出しプログラム。
コード(getline.rb)
#!/usr/bin/env ruby # -*- coding: utf-8 -*- len_of_N = 4 # 4で決め打ち qidx = ARGV.shift.to_i # start from 0 tgtfn = ARGV.shift idxfn = ARGV.shift || tgtfn + ".ary" tfsz = File.size(tgtfn) ifsz = File.size(idxfn) raise if qidx < 0 or qidx * len_of_N >= ifsz buf = "" fi = open(idxfn) fi.seek(qidx * len_of_N, IO::SEEK_SET) fi.read(len_of_N, buf) ixf = buf.unpack("N")[0] ixt = if fi.pos < ifsz fi.read(len_of_N, buf) buf.unpack("N")[0] else tfsz end fi.close fh = open(tgtfn) fh.seek(ixf, IO::SEEK_SET) fh.read(ixt - ixf, buf) fh.close print buf
実行例
$ ./getline.rb 2 test.dic Yokohama