第33回 Ruby/Rails 勉強会 - 演習 1
宿題の添削はしてくれるんだろうか?
演習 1
なんだか力ずくでやってしまった。
#! /usr/local/bin/ruby19 # -*- coding: utf-8; -*- require 'optparse' # 指定されたオプションを覚える option = { output: '.', # 出力先 prefix: '', # prefix count: 2, # 分割数 } # オプションの指定 parser = OptionParser.new parser.on('-d n', '--divide', 'divide to n.'){|n| option[:count] = Integer(n)} parser.on('-o dir', '--output-dir', 'output directory.'){|o| option[:output] = o.sub(%r[/$], '')} parser.on('-p prefix', '--prefix', 'prefix of filename.'){|p| option[:prefix] = p} parser.banner = <<USAGE # csv ファイルを複数受け付けるよ usage: #{File.basename $0} [options] [csv-file ...] options: USAGE # コマンドライン引数の解析 begin parser.parse!(ARGV) rescue Object =>e STDERR.puts "#{File.basename $0}: #{e.to_s}" STDERR.puts parser.help exit 1 end # prefix の決定 # # prefix を指定されなかったら basename を使う。 # ARGF から複数のファイルを受け取ったら、ファイルごとに変える。 # 標準入力なら 'stdin' def guess_prefix(prefix, fn) prefix = File.basename(fn, ".*") if prefix.empty? prefix = 'stdin' if prefix == '-' prefix end # 分割後のファイル名の Array def output_files(count, dir, prefix) (0...count).map{|i| "%s/%s%03d.csv" % [dir, prefix, i]} end # csv を分割 # # 各行を count 個に分割 def divide_csv(src, count, files) n = ((src.count(',')+1.0)/count).ceil # ファイルごとのカラム数 data = src.split(/\s*,\s*/).each_slice(n) files.each do |file| begin file.puts data.next.join(",") rescue StopIteration # カラムが足らんがな file.puts end end end files = [] # 分割後のファイル pre = "" # 処理中の prefix ARGF.each_line do |buf| tmp = guess_prefix(option[:prefix], ARGF.filename) # prefix が変わったら 再オープン if pre != tmp files.each{|f| f.close} files = [] output_files(option[:count], option[:output], tmp).each do |fn| files << open(fn, "w") end pre = tmp end # 分割するぞ divide_csv(buf, option[:count], files) end # プロセス終了と共に files もクローズされる
OptionParser って、
-d n -o dir -p pre
を
-dop n dir pre
って書けないんだね。知らなかった。