Grep in Ruby
Here’s an attempt at building a grep-alternative in Ruby…
#!/usr/bin/env ruby
#
# Author: Katkam Nitin Reddy
# Email: <redknitin@gmail.com>
# Date: 2023-02-08
# Description: Replacement for grep with support for lookahead/lookbehind
#
require 'optparse'
require 'colorize'
def process(options)
input = File.read options[:inputfile] unless options[:inputfile]=='-'
input = ARGF.read if options[:inputfile]=='-'
# input = STDIN.gets if options[:inputfile]=='-' # This returns only 1 line, so we use ARGF.read instead
input.each_line do |iter_line|
if not (mat = iter_line.match(options[:pattern])).nil?
if options[:output_match_group]==0
before_text = iter_line[0..mat.begin(0)-1] unless mat.begin(0)==0
match_text = mat[0]
after_text = iter_line[mat.end(0)..]
puts "#{before_text}#{match_text.red}#{after_text}"
else
puts mat.captures[options[:output_match_group]-1]
end
# p '--'
end
end
end
# Entry point for the application; parse args and call process()
def main
# Default options
options = {
processing_type: :normal,
output_match_group: 0
}
# Define the parser
parser = OptionParser.new do |opts|
opts.banner = 'Usage: rp.rb <pattern> <file>'
opts.on('-e PATTERN', '--pattern=PATTERN', 'Regex Pattern') do |the_param|
options[:pattern] = the_param
end
opts.on('-f FILENAME', '--file=FILENAME', 'Input file') do |the_param|
options[:inputfile] = the_param
end
opts.on('-o CAP_GROUP_NUM', '--matchgroup=CAP_GROUP_NUM', 'Specify captured group number to output') do |the_param|
options[:output_match_group] = the_param.to_i
end
end
# Parse the ARGV
remaining_args = parser.parse!
# Take parameters not passed as arguments
# Pop returns in reverse order, so we start with the right-most argument first
# Take the input file if there is nothing being piped
if STDIN.tty? and not options.has_key? :inputfile # STDIN.tty? returns false if we have piped content
options[:inputfile] = remaining_args.pop
elsif not options.has_key? :inputfile and not options.has_key? :inputfile
options[:inputfile] = '-'
end
# Take the pattern
if not options.has_key? :pattern
options[:pattern] = remaining_args.pop
end
process options
end
# Enables us to use this as a library of functions
main if __FILE__ == $0