From: "Brian Schröder" Date: 2005-07-29T23:39:09+09:00 Subject: Re: Sed -> Ruby : .. and ... On 29/07/05, Keith Fahlgren wrote: > Hi all, > > Thanks for the helpful responses. Many corrected me, rightly, for > writing a whole program rather than just using a one-liner and for > modifying the file in place rather than setting up temporary files. I > was concentrating on my task, making a template to replace thousands of > lines of sed files rather than doing a single replacement. > > My larger problem still revolved around doing a bunch matches inside an > range. > > On Thursday 28 July 2005 5:46 pm, mathew wrote: > > working_file.gsub!(/(?=BEGIN RANGE)(.*?)(?=END RANGE)/m) {|| > > $1.gsub(/MATCH/m, 'REPLACEMENT') > > } > > Matthew pointed out an easier way to get around it but I had rejected > that method from the start because I wanted to be able to nest ranges > (like I can in sed). > > I think the problems with my inital attempts was assuming .read was > returning an array rather than a string. Slapping .to_a to the end > solved that bit and the program now works as expected, I think. > > Here's my solution (though I'd still love comments): > > > #!/usr/bin/env ruby > files = ARGV > > files.each do |arg| > puts "\nOpening file #{arg}" > f = File.open(arg) > working_file = f.read.to_a > f.close > working_file.each do |aline| > if aline =~ /BEGIN RANGE/ .. aline =~ /END RANGE/ > #nest if lines like above as many times as needed for nested > ranges > aline.sub!(/MATCH/,'REPLACEMENT') > end > end > > puts "\nDoing ACTION in #{arg}" > fnew = File.new("#{arg}.tmp", "w") > puts "\nWriting #{fnew} now" > fnew.print(working_file) > fnew.close > end > > > > Thanks, > Keith > > My approach would be something along these lines: bschroed@black:~/svn/projekte/ruby-things$ cat test test Range1 test1 Range2 test2 EndRange2 test3 EndRange1 bschroed@black:~/svn/projekte/ruby-things$ cat ranges.rb ARGV.each do | filename | result = [] File.read(filename).split("\n").each do | line | if line =~ /^Range1/ .. line =~ /^EndRange1/ if line =~ /^Range2/ .. line =~ /^EndRange2/ result << " - " + line else result << " - " + line end else result << "- " + line end end puts filename puts "-" * filename.length puts result puts "-" * filename.length puts end bschroed@black:~/svn/projekte/ruby-things$ ruby ranges.rb test test ---- - test - Range1 - test1 - Range2 - test2 - EndRange2 - test3 - EndRange1 ---- regards, Brian -- http://ruby.brian-schroeder.de/ Stringed instrument chords: http://chordlist.brian-schroeder.de/