Ruby版findコマンド - rfind
どうもfindコマンドは難しすぎて頭の悪い俺には覚えられん。ここは慣れ親しんだRubyで。
今まで何人の人がやったかわからないけど俺版を瞬時にでっちあげた。
#!/usr/bin/env ruby # Ruby version of `find' require 'pathname' require 'rubygems' require 'active_support/core_ext/numeric' class PathnameExt < Pathname def =~(other) to_s =~ other end end def rfind(expr, *paths) rfind(expr, *STDIN.read.split(/\r?\n/)) if paths.empty? paths.each do |path| begin _ = PathnameExt.new path puts path if _.instance_eval(expr) rescue end end end if !ARGV[0] or ARGV[0]=='--help' puts "Usage: rfind expr [files] expr is Ruby expression which _ is Pathname object with extension, " else rfind *ARGV end
純粋なfindというわけではなく、実際は条件式に一致するファイルを絞り込むコマンド。
rfind RUBY_EXPRESSION [FILES]
のように使う。FILESのうち、RUBY_EXPRESSIONの条件を満たすもののみ表示する。FILESが与えられない場合は標準入力から読み込む。
使いやすいようにactive_supportの力でN.days.agoなどの表記が使えるようになっている。さらに、ファイル名の正規表現マッチのために =~ が使えるようになっている。
追記:instance_evalを使うことでなるべく_を省略できるようにしてみた。
3日以内に更新されたファイル・ディレクトリを取得するには、
$ rfind '_.mtime > 3.days.ago' * $ find | rfind '_.mtime > 3.days.ago' $ find | rfind 'mtime > 3.days.ago'
拡張子がtxt以外のファイルを取得するには、
$ find | rfind '_.file? and _ !~ /\.txt$/' $ find | rfind 'file? and _ !~ /\.txt$/'
まぁこれくらいのコードならRuby流に「ソースがドキュメント」ということで(笑)