Rubyのeval()を使ってみる。これを使えば、 ファイルから読み込んだ文字列データを、そのままRuby処理系に渡して解釈できる。
今回は、例えば適当に定義したデータ形式のファイルから、 hashテーブルとして読み込むところをやってみたい。
データは例えば下記のようなものとする。
human { name: foo age: 12 money: 120 } dwarf { name: boo age: 200 money: 20 }
この程度なら難しいパーサーを作る必要もなく、文字列置換で以下に置き換えてしまう。
@list << { 'type'=>'human', 'name'=>'foo', 'age'=>'12', 'money'=>'120', } @list << { 'type'=>'dwarf', 'name'=>'boo', 'age'=>'200', 'money'=>'20', }
これはもう下記のように正規表現でベタに置換してしまえばいい。 (標準入力から食わせた場合)
str = '' while line = STDIN.gets case line when /^(.+?) {/ str << "@list << {" str << "'type'=>'#{$1}', " when /(.+?): (.*?)$/ str << "'#{$1}'=>'#{$2}', " when /(.+?):$/ str << "'#{$1}'=>'', " else str << line end end
あとは、evalにかけるだけ、
@list = [] eval(str)
と、Ruby内でhashテーブルの出来上がり。
さて、とりあえず上記のような形式のデータを変換して、 スペースで区切った形式に出力スクリプト(conv.rb)を作った。
■使い方:
$ cat data | conv.rb TYPE NAME AGE MONEY human foo 12 120 dwarf boo 200 20
■ソースコード(conv.rb):
#!/usr/bin/ruby def print_key(rcd, keys) rcd.each do |k,d| print "#{k.upcase} " if keys.length==0 || keys.include?(k) end puts "" end def print_record(rcd, keys) rcd.each do |k,d| _d = if d=="" then "-" else d end print "#{_d} " if keys.length==0 || keys.include?(k) end puts "" end # # parse and import datas # str = '' while line = STDIN.gets case line when /^(.+?) {/ str << "@list << {" str << "'type'=>'#{$1}', " when /(.+?): (.*?)$/ str << "'#{$1}'=>'#{$2}', " when /(.+?):$/ str << "'#{$1}'=>'', " else str << line end end # # make record data # @list = [] eval(str) # # print record date # print_key @list[0], ARGV if @list.length > 0 @list.each do |r| print_record r, ARGV end