Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!feeder.news-service.com!novso.com!news.skynet.be!talisker.lacave.net!lacave.net!not-for-mail From: Brian Candler Newsgroups: comp.lang.ruby Subject: Re: replace lines in a file using hash key-value pairs Date: Fri, 20 May 2011 03:03:53 -0500 Organization: Service de news de lacave.net Lines: 54 Message-ID: References: <235a8d6f428573541046a02f84b60764@ruby-forum.com> NNTP-Posting-Host: bristol.highgroove.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Trace: talisker.lacave.net 1305878667 35657 65.111.164.187 (20 May 2011 08:04:27 GMT) X-Complaints-To: abuse@lacave.net NNTP-Posting-Date: Fri, 20 May 2011 08:04:27 +0000 (UTC) In-Reply-To: <235a8d6f428573541046a02f84b60764@ruby-forum.com> X-Received-From: This message has been automatically forwarded from the ruby-talk mailing list by a gateway at comp.lang.ruby. If it is SPAM, it did not originate at comp.lang.ruby. Please report the original sender, and not us. Thanks! For more details about this gateway, please visit: http://blog.grayproductions.net/categories/the_gateway X-Mail-Count: 383506 X-Ml-Name: ruby-talk X-Rubymirror: Yes X-Ruby-Talk: Xref: x330-a1.tempe.blueboxinc.net comp.lang.ruby:4800 Johan Martinez wrote in post #999809: > configfile = File.open("#{configfilename}","r+") > > # read filelocations hash - for each key, replace with value > depprops.get_filelocations.each_pair do > |key,value| > puts " #{key} #{value}" > configfile.each do > |line| > puts line > # puts line if line.match("#{key}") > # line.sub!("/#{key}/","#{key} = #{value}") > end > end These are nested loops. For the first key,value pair iteration, configfile.each goes through each of the lines. After that the file is exhausted, and .each won't do anything more. If you want to do that, you have to either .rewind or open the file again: depprops.get_filelocations.each_pair do |key,value| File.open(configfilename) do |configfile| configfile.each_line do |line| ... end end end Using the block form of File.open ensures that it's closed after each iteration. Of course, this is probably a very inefficient way to do what you want; I'd rather iterate through the file once, and for each line do the key/value substitutions. But then you get the results in a different order, of course. > Also, is there any other way to implement search search-replace for all > matching lines in a files based on hash/yaml file. Probably the most efficient way is to build a single regex that matches all the substitutions in one go. subs = {"hello"=>"goodbye", "world"=>"cruel life"} keys = subs.keys.map { |k| Regexp.escape(k.to_s) } pattern = Regexp.new("(?:#{keys.join("|")})") lines = "hello world\ntesting\nhello again hello\n" lines.each_line do |line| puts line.gsub(pattern) { |k| subs[k] } end -- Posted via http://www.ruby-forum.com/.