From: Keith Fahlgren Date: 2005-07-29T01:18:26+09:00 Subject: Sed -> Ruby : .. and ... Hi all, What's the deal with all the different versions of http://pleac.sourceforge.net/pleac_ruby/patternmatching.html on the web? I've found that the most complete document and most helpful on this sort of Ruby regular expression tutelage. It seems like documentation on adopting sed to Ruby would be helpful. [I'll write something if I ever understand it.] Surprise: I'm trying to adapt some sed scripts into Ruby programs. I'd like feedback on how to make them more idiomatic/Rubylicious and help on making 2nd one work. Here's my essential program for a line of sed that seems to work correctly. I dunno if there's a better way to express it: --------------------------------------------------- sed: s/MATCH/GLOBAL REPLACEMENT/g ruby: #!/usr/bin/env ruby files = ARGV files.each do |arg| f = File.open(arg) puts "\nOpening file #{f}" working_file = f.read working_file.gsub!(/MATCH/,'GLOBAL REPLACEMENT') puts "\nDoing ACTION in #{arg}" f = File.new(arg, "w") puts "\nWriting #{f} now" f.print(working_file) f.close end --------------------------------------------------- Here's the one I have problems with (we had a working Perl equivalent but are trying to abandon Perl). sed: /BEGIN RANGE/,/END RANGE/{ s/MATCH/REPLACEMENT/g } ruby: [same beginning] if working_file =~ /BEGIN RANGE/ .. working_file =~ /END RANGE/ # INCLUSIVE use ... if you want non inclusive working_file.sub!(/MATCH/,'REPLACEMENT') end [same ending] ----------------- The above works fine on the first occurence of MATCH but won't do any of the subsequent matches in the document. I subsitute 'gsub' but that will just effect all of the places in the document, ignoring my if statement. Suspecting a lack of understanding of the way the range works and find and old thread on the mailing list ( http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/73674 ) but don't really follow it. I've come up with the following as a tentative replacement but it's not setting 'aline' in 'working_file' after it substitues it. [same beginning] working_file.each do |aline| # Read each line, right? if aline =~ /BEGIN RANGE/ .. aline =~ /# end of CellContent/ aline.sub!(/Cell/,'CellHeading2') end end [same ending] ----------------- [Running up against my own ignorance now of the range thingie] Here's my failing test: #!/usr/bin/env ruby files = ARGV files.each do |arg| f = File.open(arg) puts "\nOpening file #{f}" working_file = f.read puts "Subsitutions occuring now" working_file.each do |aline| if aline =~ /BEGIN RANGE/ .. aline =~ /END RANGE/ aline.sub!(/MATCH/,'REPLACEMENT') puts "#{aline}" end end puts "\nOutput of working_file" puts "#{working_file}" puts "\nDoing ACTION in #{arg}" f = File.new(arg, "w") puts "\nWriting #{f} now" f.print(working_file) f.close end ----------------- Here's the test file: a lonely line BEGIN RANGE MATCH END RANGE another lonely line BEGIN RANGE MATCH nothing here MATCH END RANGE don't change MATCH ----------------- Here's the output: > ,rtest2 ,test.txt Opening file # Subsitutions occuring now BEGIN RANGE REPLACEMENT END RANGE BEGIN RANGE REPLACEMENT nothing here REPLACEMENT END RANGE Output of working_file a lonely line BEGIN RANGE MATCH END RANGE another lonely line BEGIN RANGE MATCH nothing here MATCH END RANGE don't change MATCH Doing ACTION in ,test.txt Writing # now Thanks for your help, Keith