Rethinking the Generic Ruby Oneliner

So I was asking myself the question... What ruby run time options
would I add to make oneliners easier.

Basically awk started it all with the notion of a loop that iterated
over a file allowing patterns and actions per line...

This is enshrined in ruby as..
   ruby -nple 'do whatever with $_'
or...
   ruby -nplae 'do whatever with $_ split into $F'

However, the ruby variants...
   IO.read( filename).gsub( %r{whatever}mx){|match| }
and
   IO.read( filename).scan( %r{whatever}mx){|match| }
are way more powerful.

The next Big Thing in one liners was the perl -i.bak option. Ruby has it too.

Invariably the -i.bak option is used in conjunction with the "find" and "xargs"
commands to find the files.

Like so...
   find . -name '*.[hc]' | xargs ruby -i.bak -nple 'whatever'

But Ruby has an excellent and way less cryptic find facility...

require 'find'

Find.find( startPath) do |path|
   next unless path =~ %r{ \.[hc] $ }x
   # Do something with path
end

Wouldn't it be nice if we could ...

ruby --find startPath --matching pathRegex --scan scanRegex -e action
   or
ruby --find startPath --matching pathRegex -i.bak --gsub searchRegex -e "replaceString"

with suitable one letter '-' options replacing the --long options for golfing.

ruby --find startPath --matching pathRegex --prune 'pruneRegex' --scan scanRegex -e action

Would effectively expand to something vaguely like...
require 'find'
Find.find( *startPath.split(',')) do |path|
   next unless path.match( pathRegex)
   Find.prune if path.match( pruneRegex)
   IO.read(path).scan(scanRegex){|match| action}
end

and...
ruby --find startPath --matching pathRegex -i.bak --gsub searchRegex -e "replaceString"

Would effectively expand to something vaguely like...
require 'find'
Find.find( *startPath.split(',')) do |path|
   next unless path.match( pathRegex)
   Find.prune if path.match( pruneRegex)
   backup = path + '.bak'
   File.rename( path, backup)
   open( path, 'w') do |outf|
     outf.syswrite( IO.read( backup).gsub(searchRegex){|match| replaceString})
   end
end

Any suggestions before I write up an RCR?

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand

Maybe:

ruby -rmylibrary -e "replaceString" -- --find startPath --matching

pathRegex -i.bak --gsub searchRegex

If that's too long, maybe a shell/program wrapper ^^

myruby --find startPath --matching pathRegex -i.bak --gsub

searchRegex -e "replaceString"

I like magic best when I can tear it apart -- and you have all the
tools now to put it to the test.

Paul

If you call it x.rb then you can have ruby -rx ...

···

On Mon, Mar 26, 2007 at 07:55:05AM +0900, Paul Stickney wrote:

Maybe:
>>ruby -rmylibrary -e "replaceString" -- --find startPath --matching pathRegex -i.bak --gsub searchRegex

If that's too long, maybe a shell/program wrapper ^^
>>myruby --find startPath --matching pathRegex -i.bak --gsub searchRegex -e "replaceString"

Or create a shell script ("rubyfind") that does the command line parameter interpretation. You could even implement the shell script in ruby making your life much easier. :slight_smile:

Kind regards

  robert

···

On 26.03.2007 08:00, Brian Candler wrote:

On Mon, Mar 26, 2007 at 07:55:05AM +0900, Paul Stickney wrote:

Maybe:

ruby -rmylibrary -e "replaceString" -- --find startPath --matching pathRegex -i.bak --gsub searchRegex

If that's too long, maybe a shell/program wrapper ^^

myruby --find startPath --matching pathRegex -i.bak --gsub searchRegex -e "replaceString"

If you call it x.rb then you can have ruby -rx ...