Replace lines in a file using hash key-value pairs

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.

  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

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.

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) }

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

Thanks for the reply Johannes and Brian. Brian, I really appreciate for
explaining the problem with my code. Thanks again…

cheers,
jM.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs