今日は久々にRubyに触ったのでネタにブログ書いてみる。(はてな記法の練習も兼ねて)
背景
入力ファイル名と出力ファイル名をコマンドライン引数に渡すと入力ファイルを変換して出力ファイルを作るプログラムを作ったのだが、複数のファイルを一回一回手打ちで実行するのもあれなので、一括で変換するスクリプトを書こうと思った。
プログラムを手打ちで実行するやり方はこんな感じ
./hoge.exe infile outfile
仕様
Windows上のプログラムなので、他人のマシンでも使えることを考えるとバッチスクリプトが良かったのかもしれないが面倒臭いのでRubyスクリプトで作ることにした。
呼び出し方はこんな感じにした
./script.rb infolder outfolder
ただし
- script.rbはcygwin上で呼び出す(おいw)
- infolderの中には入力ファイルが複数含まれていて、他のファイルがないものとする
- script.rbとhoge.exeとinfolderは同一フォルダにおく
- 入力ファイルの拡張子を.in、出力ファイルの拡張子を.outとする
- カレントフォルダにoutfolderを作成し、変換後の出力ファイルを保存する
とする
方法
Rubyがもともとそんなに使ってないのと久しぶりだったので、簡単な処理もぐぐったり同僚にききながらやり方を調べた。
必要な処理とやり方の表
必要な処理 | やり方 | 参考 |
---|---|---|
コマンドライン引数の使い方 | ARGV | http://www-section.cocolog-nifty.com/blog/ruby/index.html |
フォルダに含まれるファイル一覧を取得 | Dir::glob | http://www.namaraii.com/rubytips/?%A5%C7%A5%A3%A5%EC%A5%AF%A5%C8%A5%EA#l12 |
ベースネームを取得 | File::basename | http://www.namaraii.com/rubytips/?%A5%D5%A5%A1%A5%A4%A5%EB%A5%A2%A5%AF%A5%BB%A5%B9#l19 |
*1二つの配列を結合 | Array::zip | http://ref.xaio.jp/ruby/classes/array/zip |
外部コマンドの実行 | バッククォートで囲む | http://doruby.kbmj.com/yablog/20090531/ruby_1 |
結果
そしてできたスクリプトはこちら。いろいろハードコーディングしてるが・・・
script.rb #!/usr/bin/ruby if ARGV.size < 2 then exit end infolder = ARGV[0] outfolder = ARGV[1] infiles = Dir::glob("./#{infolder}/*.in") inbasenames = infiles.map {|infile| File.basename infile, ".in"} outfiles = inbasenames.map {|basename| "./#{outfolder}/#{basename}.out"} infiles.zip(outfiles).each do |inout| command = "./hoge.exe #{inout[0]} #{inout[1]}" puts command `#{command}` end
自分の環境でちゃんと動いた。