Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - Open file, find and replace multiple lines

Tags:

ruby

I'm new to ruby and was hoping someone could help me figure out how to open a file, then using gsub to find and replace by multiple conditions.

Here's what I got so far but this doesn't seem to work as the 2nd replace var overrides the first:

text = File.read(filepath)
replace = text.gsub(/aaa/, "Replaced aaa with 111")
replace = text.gsub(/bbb/, "Replace bbb with 222")
File.open(filepath, "w") {|file| file.puts replace}
like image 293
oprogfrogo Avatar asked Oct 29 '10 03:10

oprogfrogo


4 Answers

Change the third line to

replace = replace.gsub(/bbb/, "Replace bbb with 222")
like image 90
gtd Avatar answered Sep 20 '22 19:09

gtd


You're replacing from the original "text" each time, the second line needs to replace the replace:

replace = replace.gsub(/bbb/, "Replace bbb with 222")
like image 23
Adam Vandenberg Avatar answered Sep 22 '22 19:09

Adam Vandenberg


An interesting wrinkle to this is if you don't want to rescan the data, use the block form of gsub:

replace = text.gsub(/(aaa|bbb)/) do |match|
  case match
    when 'aaa': 'Replaced aaa with 111'
    when 'bbb': 'Replace bbb with 222'
  end
end

This may not be the most efficient way to do things, but it's a different way to look at the problem. Worth benchmarking both ways if performance matters to you.

like image 11
Steve Ross Avatar answered Sep 21 '22 19:09

Steve Ross


Here is a one liner

IO.write(filepath, File.open(filepath) {|f| f.read.gsub(/aaa|bbb/) {|m| (m.eql? 'aaa') '111' : '222'}})

IO.write truncates the given file by default, so if you read the text first, perform the regex String.gsub and return the resulting string using File.open in block mode, it will replace the file's content. Nifty right?

It works just as well multi-line:

IO.write(filepath, File.open(filepath) do |f|
    f.read.gsub(/aaa|bbb/) do |m|
      (m.eql? 'aaa') '111' : '222'
    end
  end
)
like image 4
Steve Benner Avatar answered Sep 18 '22 19:09

Steve Benner