Ruby - Open file, find and replace multiple lines
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}
Change the third line to
replace = replace.gsub(/bbb/, "Replace bbb with 222")
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")
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.
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
)
I might be tempted to write it like this...
#!/usr/bin/env ruby
filepath = '/tmp/test.txt'
File.open filepath, 'w' do |f|
$<.each_line do |line|
f.puts line.gsub(/aaa/,
'Replaced aaa with 111').gsub /bbb/, 'Replace bbb with 222'
end
end
Another nice extension to @steveRoss's answer above, using variables:
aktivBold = 'AktivGrotesk_Bd.ttf'
clarityBold = 'Clarity-Bold.otf'
files.each do |file_name|
text = File.read(file_name)
replace = text.gsub(/(#{aktivBold}|#{aktivLight}|#{aktivMedium})/) do |match|
case match
when aktivBold
clarityBold
when aktivLight
clarityLight
when aktivMedium
clarityMedium
end
end
File.open(file_name, "w") { |file| file.puts replace }
end
These are not string literals but variables
精彩评论