ackぽい再帰的grepを実装してみました
id:ha-tan:20060601:1149174989で触れた再帰的grepをRubyで実装してみました。ackに比べるとオプションがぜんぜん足りませんが、まぁそれはカスタマイズの範囲ということで。
ファイル: rrr.rb
#!/usr/bin/env ruby require 'ostruct' $opts = OpenStruct.new(:debug => 0, :ignore_case => false) def match_all_pattern?(line, patterns) patterns.each do |pattern| return false if line !~ pattern end true end def grep(filename, patterns) first_f = true open(filename, 'r') do |file| while line = file.gets break if line.count("\000") > 1 # skip binary file. next unless match_all_pattern?(line, patterns) if first_f print "\n\033[1;32m#{filename}\033[0m\n" # bold green. first_f = false end patterns.each do |pattern| line.gsub!(pattern, "\033[30;43m\\&\033[0m") # black on yellow. end printf "%6d:%s", file.lineno, line end end end if __FILE__ == $0 require 'find' require 'optparse' Version = '0.1a' OptionParser.new do |opt| opt.banner = "Usage: rrr.rb [options] pattern..." opt.on('-d', '--debug', 'enable debug mode.') do $opts.debug += 1 end opt.on('-i', '--ignore-case', 'ignore case distinctions.') do $opts.ignore_case = true end opt.parse!(ARGV) if ARGV.size < 1 puts opt.help exit end end patterns = ARGV.collect do |arg| Regexp.new(arg, $opts.ignore_case) end Find.find('.') do |filename| Find.prune if filename =~ %r!/(:?CVS|RCS|.svn|blib)! next if FileTest.directory?(filename) next if filename =~ /(?:~|\.bak)$/ puts filename if $opts.debug > 0 grep(filename, patterns) end end
BUGS。