Sunday, March 01, 2009

rgrep.rb

「オブジェクト指向スクリプト言語Ruby」のサンプルを基にRuby版grepを作った
例のgetoptはRuby1.8.7以降では非推奨となっており
代わりにoptparseを使う

   1  #!/usr/local/bin/_ruby

   2  # encoding: utf-8

   3  require "optparse"

   4  require "find"

   5  

   6  def grep(file, filename, &block)

   7    file.each_line do |line|

   8      if line =~ block.call

   9        $exit_status = 0

  10        unless OPTS[:q]

  11          print "#{filename}:" if OPTS[:h]

  12          print "#{$.}:" if OPTS[:n]

  13          line = line.gsub!(block.call, "\033[7m\\&\033[m") unless OPTS[:p]

  14          print "#{line}"

  15        end

  16      end

  17    end

  18  end

  19  

  20  def search_file(filenames, &block)

  21    Find.find(*filenames) do |filename|

  22      begin

  23        unless File.directory?(filename)

  24          open(filename) do |file|

  25            grep(file, filename, &block)

  26          end

  27        end

  28      rescue Errno::ENOENT, Errno::EACCES

  29        $stderr.puts "rgrep: #{$!}" unless OPTS[:s]

  30      end

  31    end

  32  end

  33  

  34  def print_usage

  35    $stderr.puts("usage: rgrep [-[hiknpqs]] <expr> [<files...>]")

  36    $stderr.puts("Try 'rgrep --help' for more information.")

  37  end

  38  

  39  def print_help

  40    $stderr.print <<-HELP

  41    usage: rgrep [-[hiknpqs]] <expr> [<files...>]

  42            -h    Suppress the prefixing of filenames on output

  43                  when multiple files are searched.

  44            -i    Ignore case distinctions in both the pattern

  45                  and the input files.

  46            -k    Convert kanji code automatically.

  47            -n    Prefix each line of output with the line number

  48                  within its input files.

  49            -p    Suppress highlight.

  50            -q    Quiet; suppress normal output.

  51            -s    Suppress error messages about nonexistent

  52                  or unreadable files.          

  53  HELP

  54  end

  55  

  56  OPTS = {}

  57  def set_options(options)

  58    begin

  59      opt = OptionParser.new

  60      opt.on('-h') { |v| OPTS[:h] =}

  61      opt.on('-i') { |v| OPTS[:i] =}

  62      opt.on('-k') { |v| OPTS[:k] =}

  63      opt.on('-n') { |v| OPTS[:n] =}

  64      opt.on('-p') { |v| OPTS[:p] =}

  65      opt.on('-q') { |v| OPTS[:q] =}

  66      opt.on('-s') { |v| OPTS[:s] =}

  67      opt.on('--help') { |v| OPTS[:help] = v }

  68      opt.parse!(options)

  69    rescue Exception => e

  70      $stderr.puts e

  71      print print_usage

  72      exit(2)

  73    end

  74    

  75  end

  76  

  77  def main

  78    $exit_status = 1

  79    set_options(ARGV)

  80    trap("INT") do

  81      exit(1)

  82    end

  83    if OPTS[:help]

  84      print_help

  85      exit(2)

  86    end

  87    if ARGV.empty?

  88      print_usage

  89      exit(2)

  90    end

  91    pattern = ARGV.shift

  92    search_file(ARGV) { Regexp.new(pattern, OPTS[:i]) }

  93    exit($exit_status)

  94  end

  95  

  96  main


No comments: