From: Dan George Date: 2007-09-20T17:35:04+09:00 Subject: Re: YAML & readlines & modify text files On Sep 20, 1:41 am, Stefano Crocco wrote: > Alle gioved� 20 settembre 2007, Dan George ha scritto: > > > > > On Sep 20, 12:39 am, Stefano Crocco wrote: > > > Alle mercoled� 19 settembre 2007, Dan George ha scritto: > > > > CATEG being another line inside the text files... and the problem > > > > might be because the Name-line isn't always above the Link-line. I > > > > could have n lines between or below, what I'm trying to say is that I > > > > don't know where the Name-line is inside the texts files. > > > > This changes everything. I assumed (according to the example lines you > > > posted) that each Link-line had the corresponding Name-line above it. > > > But, if there isn't a relation between the position of the two kind of > > > lines, how can you know what to put in the link line? I mean, what is the > > > relation which connects a Link-line and the corresponding Name-line? > > > Since (from what you say now) the position of the two kind of lines are > > > random (as far as this problem is concerned, at any rate) are you able, > > > given a single Link-line, to understand which is the corresponding > > > Name-line? If yes, how? Whithout knowing this, I can't help you. > > > > Stefano > > > All I can say is that in each text file there will only be one Name- > > line and one Link-line. The only connection between this 2 lines is > > that the Link uses the shorter version of what is written in the Name- > > line (i.e. if the Name-line: New York the Link line will use NY) > > > Isn't it possible to read the Name-line, take the correspond value > > from the YAML file, store it in a variable (string?) inside the code > > and then use it in the Link-line, when going to the next text file > > read again the Name-line and take the value from YAML and so on... > > If each file contains only one Name-line and one instance of the corresponding > Link-line, this should work: > > require 'yaml' > > lnk='blabla.something.' > op = '&=bla' > hash = File.open('name.yaml'){|f| YAML.load f} > > Dir.glob('**/*.txt').each do |f| > lines = File.readlines f > name = nil > link_idx = nil > lines.each_with_index do |l, i| > if l.match(/Name-line:\s+(.*)$/) then name $1 > elsif l.match(/Link-line/) then link = i > end > break if name and link_idx > end > if name > rep = hash[name] > if rep > lines[link_idx]="Link-line: #{lnk}#{rep}#{op}" > File.open(f, 'w'){|of| of.write lines} > else puts "name.yaml doesn't contain an entry for #{name} (file #{f})" > end > else puts "Couldn't find a Name line in file #{f}" > end > end > > For each file, it loops each line looking for a Name-line or a Link-line. When > it finds the former, it stores the name in the name variable; when it finds > the latter, it stores its index in the link_idx variable. When both are > found, the loop stops (no point in examining the remaining lines). If a name > has been found and it corresponds to an entry in the hash, the line with > index link_idx is replaced with a new one (I removed the call to gsub!, since > we're rebuilding the entire line, but you can put it back, if you need it), > then the array is written to the file. If the Name-line wasn't found, or if > the hash doesn't contain an entry for it, an error message is printed on > screen and the next file is processed. > > I hope this helps > > Stefano Thanks for your reply Stefano! I had to do: link_idx = nil.to_i otherwise I would get this error: `[]': no implicit conversion from nil to integer (TypeError) And it seems to be working but if I use this: lines[link_idx]="Link-line: #{lnk}#{rep}#{op}" the Name-line is removed and is replaced by the "Link-line: #{lnk}#{rep}#{op}" but the old Link-line = 0 is kept too. If I use lines[link_idx].gsub!(/Link-line.*/, 'Link-line: '+lnk+rep +op) nothing happends, no errors, no modified files, no nothing. I don't see anything wrong with the gsub! so what might be the problem?