[Ruby] 二時間の仕事を一秒で片付けてくれる(かもしれない)三行スクリプト。

by tanabe on December 12, 2007

「テキストファイルの各行に一括で同じような処理をして、その結果を得たい」というようなことはよくあります。特に職場が Windows な環境だと CUI のツールが貧弱で、ついエディタでやってみたりしてしまって、半分くらいやったところで睡魔に襲われてどこまで作業したかわからなくなって全部やり直したり。

こんなコードを PATH の通ったところにおいただけで、非常に重宝しているのでご紹介します。はまったときには、笑っちゃうくらい作業効率が上がるかも。

script = ARGV.shift || ''
lines = $stdin.readlines.map {|li| li.chomp}
puts eval(script)

ファイル名に firter とでも名付けてやって呼び出してみます。

たとえば、c:\ruby\bin\rake ファイルからコメントで始まる行だけを抜き出したいときはこんなかんじ。

type c:\ruby\bin\rake | firter "lines.select {|s| s =~ /^#/}"

lines という変数名で標準入力の各行にアクセスできます。

各行に対して、前後の空白とか除去して、重複を除いて、ソートして、空行は除外した結果がほしい、なんてときも、これだけ。

type test.txt | firter "lines.map {|s| s.strip}.uniq.sort.delete_if {|s| s == ''}"

Ruby の強力な Enumerable モジュールと String クラスと正規表現で、大抵の用事は片付きます。

元々すぐコード書いちゃう人はちょっと手間が省けるくらいなんじゃ、とか、それ per(ry とか、それ aw(ry とか、ありますが、慣れると手放せません。

あと、

@ruby "c:\ruby\bin\firter" %* 

とか書いたファイルを firter.cmd として置いておくとうれしいかも。(c:\ruby\bin は適当に調整してください。)

s/firter/filter/ という指摘は受け付けませんのであしからず。


この記事へのコメント
すごい。便利そうです。
ブログで紹介させていただきました。
ところで、firterはfilterでは?
Posted by shunsuk at December 12, 2007 22:04
ご紹介どうもありがとうございました!

firter はもちろん filter が正解です。
r にしている理由は二つあって、Linda -> Rinda のように R に置換した名前を付けてみたかったということと、filter だと別のプログラムと名前が重複しそうだったのでそれを避けたかったためです。
Posted by tanabe at December 14, 2007 03:38
ruby -nオプションなんかも結構同じ用途に使えますよね。
Posted by mis at December 18, 2007 20:03
-n オプションなんてものがあるんですね。初めて知りました。

type c:\ruby\bin\rake | ruby -n -e "puts $_ if $_ =~ /^#/"

おー、なるほど。
たしかにこれで十分な場合も多いですね。
どうもありがとうございます。
Posted by tanabe at December 18, 2007 23:48