Alle mercoledì 22 agosto 2007, Dan George ha scritto:
I recently started to take an interest in Ruby programming and with
the help of some people and by reading Learn to program by Chris Pine
I made myself a little program that has come to a halt because I don't
know if or how I can use an external file where I store the strings I
want to search and replace in text type files.
This is what I have so far:
txt_files = Dir.glob('**/*.txt').each do |path|
puts path
txts = path.to_s
file = File.open(txts).readlines.each { |line|
if line.match(/PROMOS:/)
then line.gsub!(/PROMO1=[A-Za-z0-9]+/, 'PROMO1=some_text')
end }
file2=File.open(txts, "w")
file2.write( file )
end
What I want is to be able to use an external file where I store the
values I want to search and replace with "line.gsub!" eg.: "/PROMOn=[A-
Za-z0-9]+/, 'PROMOn=some_other_text'".
I will need to use RubyScript2Exe because I'm not sure that on some
other machines I will have ruby installed and it's easier to just put
the strings I want to search and replace in an external file that is
located in the same folder as the script or on a predefined path.
Any ideas, hints, improvements and critiques are highly welcome.
First some comments about your code:
* path is already a string, so calling to_s on it does nothing.
* You can replace the File.open(txts).readlines part with
File.readlines(txts), which is (in my opinion) clearer and doesn't force you
to remember to close the file (which by the way, you don't do).
* When you write to file2, you can use the block form of File.open, which
takes care of closing the file for you.
Here's how what I'd have written:
Dir.glob('**/*.txt').each do |path|
lines = File.readlines(path)
if line.match(/PROMOS:/)
lines.map!{|l| l.gsub(/PROMO1=[A-Za-z0-9]+/, 'PROMO1=some_text')
end
File.open(path, 'w'){|f| f.write lines}
end
As you can see, I've also replaced the each/gsub! combination with map!/gsub,
which, in my opinion makes clearer what you're doing (changing the contents
of the array).
As for storing the search/replacement pairs on a file, I'd use YAML. It's
included in the standard library, so there shouldn't be problems with
RubyScript2Exe. You can get information on yaml for ruby at
http://yaml4r.sourceforge.net/ (look in particular at the cookbook and doc
sections). A simple example could be this:
'PROMO1=[A-za-z0-9]+': 'PROMO1=some_text'
'PROMO2=[A-za-z0-9]+': 'PROMO1=some_other_text'
...
When read into ruby using YAML.load, this would return the following hash:
{
'PROMO1=[A-za-z0-9]+' => 'PROMO1=some_text',
'PROMO2=[A-za-z0-9]+' => 'PROMO1=some_other_text'
}
You could then create regexps using Regexp.new. (Actually, you can also store
the regexps directly in the yaml file, prefixing them with the
string !ruby/regexp, but I think the file is easier to read/write this way).
I hope this helps.
Stefano