0

I have to following function

#------------------------------------------------------------------------------
# This function just executes one-liner sed command
# to add "line2" after the line that contains "line1"
# in file "file_name"
#------------------------------------------------------------------------------    
def add_line2_after_line1_in_file(line1, line2, file_name, comment)
  bash comment do
    stripped_line2=line2.strip
    user 'root'
    code <<-EOC
    sed -i '/#{line1}/a #{line2}' #{file_name}
    EOC
    only_if do File.exists? file_name and File.readlines(file_name).grep(/#{stripped_line2}/).size == 0 end
  end
end

How can I call the function to produce this?

Before calling the function

This is a line
    Indented line1 \
    Indented line2 \
    Line3

After calling the function

This is a line
    Indented line1 \
    Indented line2 \
    Added line \
    Line3

I tried this to no avail

add_line2_after_line1_in_file("line1", "      line2 \\", "file", "comment")

Maybe a better function that does the same thing?

Chris F
  • 14,337
  • 30
  • 94
  • 192

1 Answers1

1

Chef comes with a Chef::Util::FileEdit Ruby class (code) that can do this type of replacement for you.

ruby_block "Add line to file [c:/path/to/your/file]" do
  block do
    file =  Chef::Util::FileEdit.new("c:/path/to/your/file")
    file.insert_line_after_match(/ line2 \\/, " line3 \\" )
    file.write_file
  end
  action :run
end

It's generally easier to get along in Chef by doing things in Ruby. You get to leave behind issues like shell escaping and quoting which are no fun.

If you have the time, try setting this up as a light weight resource and provider for each of the methods you use, so you can reuse the resource easily in any cookbooks, something like:

file_insert_after_line "c:/path/to/your/file" do
  search      /sometext/
  insert_text "new line of text"
end 
Matt
  • 68,711
  • 7
  • 155
  • 158