Reputation: 1
I’m trying to create a unix script with this scenario:
My main config file contains this line:
#BEGIN mytest
#END mytest
My input file has:
location /server/ {
(proxy config here)
}
I wanted to create a script that will search for #BEGIN mytest
and if found add another line which contains my input file, the output will be like:
#BEGIN mytest
location /server/ {
(proxy config here)
}
#END mytest
Upvotes: 0
Views: 37
Reputation: 2348
The specification is not consistent. You write 'search for "#BEGIN mytest"', but the given output is lacking '#'. I'll assume that '#' is a comment character, and you want the configuration files to have bracketing comment text of #BEGIN mytest
and #END mytest
. Given that, the following ruby script will do the trick:
#!/usr/bin/env/ruby
# update-cfg-file CFGFILE [NAME FILE] ...
#
# read CFGFILE and look for occurrences of '#BEGIN NAME', and (replace and)
# insert the contents of FILE2 inline into CFGFILE. all the original text (if
# any) from CFGFILE up to #END NAME' will be replaced by FILE2.
#
# Multiple occurrences of NAME FILE may be given, each unique name being
# associated with the contents of the subsequent FILE.
#
# if there are no occurrences of '#BEGIN NAME' within CFGFILE, no changes are
# made. If there are changes, the previous copy of CFGFILE is retained as
# CFGFILE.TIMESTAMP, where TIMESTAMP is YYYY-MM-DD.HH.MM.SS
cfgfile_name = ARGV.shift || raise "No CONFIGFILE argument"
def talk msg
$stderr.puts msg
end
files = {}
while ARGV.size > 0 do
name = ARGV.shift
name_file = ARGV.shift
break if name.empty? || name_file.empty?
if !File.exist? name_file
raise "#{name_file} does not exist"
end
files[name] = name_file
end
if files.size == 0
raise "No NAME FILE pairs given"
end
new_cfgfile = cfgfile + '.new'
cfgin = open(cfgfile, 'r')
cfgout = open(new_cfgfile, 'w')
name_re = files.keys.join('|')
changes = false
while line = cfgin.gets do
cfgout.puts line # output the line
if line =~ /^#\s*BEGIN\s+(#{name_re})\>/ # was it a boundary?
matched_name = $1
if files.key?(matched_name) # one of our keys?
talk "Found #{matched_name}"
while end_line = cfgin.gets do # skip until the closing boundary
break if end_line =~ /^#\s*END\s+#{matched_name}/
end
talk "Inserting #{name_cfg} ..."
open(files[matched_name]) do |name_cfg| # copy file into cfgout
while cfgline = name_cfg.gets
cfgout.puts cfgline
changes = true
end
end
cfgout.puts end_line # output the end_line
end
end
end
cfgin.close
cfgout.close
if changes
talk "There were changes."
timestamp = Date.now().strftime("%F_%H.%M.%S")
talk "#{cfgfile} saved with suffix of #{timestamp}"
File.rename(cfgfile, cfgfile + ".#{timestamp}")
talk "#{cfgfile} updated"
File.rename(new_cfgfile, cfgfile)
else
talk "No changes"
File.unlink(new_cfgfile)
end
exit
Upvotes: 0
Reputation: 241868
Using the r
(read file) command in sed
:
sed -e '/#BEGIN mytest/r input' config
Upvotes: 1