From: Dan George Date: 2007-09-20T03:05:07+09:00 Subject: Re: YAML & readlines & modify text files On Sep 19, 5:27 pm, Stefano Crocco wrote: > Alle mercoled� 19 settembre 2007, Dan George ha scritto: > I'm not at all sure I understand correctly what you want to do. I think you > want to replace the line under > > Name-line: Name01 > > with some text containing a string taken from the Name01 entry in the yaml > file. Is it correct? If it isn't, then please explain better what you mean. > Otherwise, read on. > > In my opinion, you're storing data in the YAML file in the wrong way, because, > at each iteration, name contains only one pair of name/replacement string, > which forces you to iterate over all the files for each document in the YAML > file (and also makes the replacing code more complicated). I think your YAML > file should contain a single hash, with the names as keys and the replacement > strings as values: > > --- > Name01: N01 > Name02: N02 > > Then, you can do the following (untested) > > require 'yaml' > lnk = 'blabla.something.' > op = '&=bla' > hash = File.open('name.yaml'){|f| YAML.load f} > Dir.glob('**/.txt').each do |path| > lines = File.readlines(path) > lines.each_with_index do |line, i| > if line.match(/Link-line/) > match = lines[i-1].match(/Name-line:\s(.*)$/)[1] > line.gsub!(/Link-line.*/, 'Link-line: '+ lnk+hash[match[1]]+ > op) if match and hash.has_key?(match[1]) > end > end > File.open(path,'w'){|f| f.write lines} > end > > When iterating on the lines, the block is passed not only the line, but also > the line number. This way, when you meet a Link-line line, you can access the > corresponding name-line using its index. It then matches the previous line > with a regexp to extract the name from it and stores the result in the match > variable. If match is not nil (i.e if the name line had the expected format) > and the name is included in hash, the replacement is performed (of course, > you can skip this test if you're confident enough in the format of the files > and in the contents of the yaml file) > > I hope this helps > > Stefano You are correct, that is what I want! I tryied what you suggested but I get some weird errors: new.rb:45: undefined method `[]' for nil:NilClass (NoMethodError) from D:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `each_with_index' from new.rb:43:in `each' from new.rb:43:in `each_with_index' from new.rb:43 from new.rb:41:in `each' from new.rb:41 Line 45 is: match = lines[i-1].match(/Name-line:\s(.*)$/)[1] Line 43 is: lines.each_with_index do |line, i| Line 41 is: Dir.glob('**/*.jad').each do |path| I don't get it, as far as I can tell the code is ok...