replace lines in a file using hash key-value pairs

Discussion in 'Ruby' started by Johan Martinez, May 20, 2011.

  1. I want to replace matching lines in a file (config.ini) based on a hash
    keys. The hash is returned by a yaml file here. Following is a code
    snippet that I have written. For each key-value pair in hash I want to
    go through all lines of a file and make string substitution for a
    matching line. However, this code is not working and I noticed that
    configfile.each method is executed only once. I appreciate any help on
    what is wrong with this code.

    <pre>

    configfilename = "configuration.ini"
    puts configfilename

    # deployment properties object
    depprops = DeployProperties.new("deploy.yaml")

    # read config file
    basedir = depprops.get_download["basedir"]

    configfile = File.open("#{configfilename}","r+")

    # read filelocations hash - for each key, replace with value
    depprops.get_filelocations.each_pair do
    |key,value|
    puts " #{key} #{value}"
    configfile.each do
    |line|
    puts line
    # puts line if line.match("#{key}")
    # line.sub!("/#{key}/","#{key} = #{value}")
    end
    end

    </pre>

    Also, is there any other way to implement search search-replace for all
    matching lines in a files based on hash/yaml file.

    Thanks
    jM.

    --
    Posted via http://www.ruby-forum.com/.
    Johan Martinez, May 20, 2011
    #1
    1. Advertising

  2. Something like that?

    hash = {"#HOST#" => "localhost", "#PORT#" => "2020" }
    fdata = File.read("config.ini")
    hash.each {|key, value| fdata.gsub(key, value) }
    File.open("config_new.ini", "w") { |f| f.write(fdata) }

    --
    Johannes
    Johannes Held, May 20, 2011
    #2
    1. Advertising

  3. Johan Martinez wrote in post #999809:
    > configfile = File.open("#{configfilename}","r+")
    >
    > # read filelocations hash - for each key, replace with value
    > depprops.get_filelocations.each_pair do
    > |key,value|
    > puts " #{key} #{value}"
    > configfile.each do
    > |line|
    > puts line
    > # puts line if line.match("#{key}")
    > # line.sub!("/#{key}/","#{key} = #{value}")
    > end
    > end


    These are nested loops. For the first key,value pair iteration,
    configfile.each goes through each of the lines. After that the file is
    exhausted, and .each won't do anything more. If you want to do that, you
    have to either .rewind or open the file again:

    depprops.get_filelocations.each_pair do |key,value|
    File.open(configfilename) do |configfile|
    configfile.each_line do |line|
    ...
    end
    end
    end

    Using the block form of File.open ensures that it's closed after each
    iteration.

    Of course, this is probably a very inefficient way to do what you want;
    I'd rather iterate through the file once, and for each line do the
    key/value substitutions. But then you get the results in a different
    order, of course.

    > Also, is there any other way to implement search search-replace for all
    > matching lines in a files based on hash/yaml file.


    Probably the most efficient way is to build a single regex that matches
    all the substitutions in one go.

    subs = {"hello"=>"goodbye", "world"=>"cruel life"}
    keys = subs.keys.map { |k| Regexp.escape(k.to_s) }
    pattern = Regexp.new("(?:#{keys.join("|")})")

    lines = "hello world\ntesting\nhello again hello\n"
    lines.each_line do |line|
    puts line.gsub(pattern) { |k| subs[k] }
    end

    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, May 20, 2011
    #3
  4. Thanks for the reply Johannes and Brian. Brian, I really appreciate for
    explaining the problem with my code. Thanks again..

    cheers,
    jM.

    --
    Posted via http://www.ruby-forum.com/.
    Johan Martinez, May 22, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Markus Dehmann

    key-value pairs: key consists of 3 ints

    Markus Dehmann, Jan 15, 2006, in forum: C++
    Replies:
    13
    Views:
    632
    Richard Herring
    Jan 23, 2006
  2. M P
    Replies:
    1
    Views:
    462
  3. Une bévue
    Replies:
    5
    Views:
    146
    Une bévue
    Aug 10, 2006
  4. Aryk Grosz
    Replies:
    13
    Views:
    230
    Trans
    Nov 18, 2008
  5. Antonio Quinonez
    Replies:
    2
    Views:
    164
    Antonio Quinonez
    Aug 14, 2003
Loading...

Share This Page