I know how to add string(or text) to end of the file as well as beginning of the file, but could not google out the way to insert string (with a variable) after/before a pattern.
For example,
root@vikas:~# cat /etc/resolv.conf
search reachvikas.com
nameserver 192.168.1.27
root@vikas:~#
Now, I want to add another nameserver like below.
root@vikas:~# cat /etc/resolv.conf
search reachvikas.com
nameserver 192.168.181.2
nameserver 192.168.1.27
root@vikas:~#
I can do this with sed easily, but just looking a way out with Ruby.
Update : I have written below code, but this replaces the last line does not adds one. I guess tweaking file.seek would help me, but not sure how.
File.open('/etc/resolv.conf', 'r+') do |file|
count = Integer(0)
file.each do |line|
#puts count
if count == 1
#puts count.to_i
file.seek(-1, IO::SEEK_CUR)
file.puts("\nnameserver 192.168.181.2")
end
count += 1
end
end
Here's a Ruby "one-liner" that does what I think you're trying to do. I created a resolv.conf
file matching your first file contents. Then the following Ruby "one-liner", which I broke into several lines for readability, searches for a line that begins with "nameserver" and inserts an arbitrary list of new namservers with IPs you define.
$ cat resolv.conf
search reachvikas.com
nameserver 192.168.1.27
$ ruby -wnl -i.$SECONDS -e '
BEGIN { server_ips = %w(
ip1
ip2
ip3
) }
if $_.start_with?("nameserver")
server_ips.each{ |ip| puts "nameserver #{ip}"; }
end
puts $_
' resolv.conf
$ ls resolv.conf*
resolv.conf resolv.conf.27729
$ cat resolv.conf
search reachvikas.com
nameserver ip1
nameserver ip2
nameserver ip3
nameserver 192.168.1.27
$ cat resolv.conf.27729
search reachvikas.com
nameserver 192.168.1.27
If you truly want it as a one-liner, you have to add semicolons where line breaks are needed:
ruby -wnl -i.$SECONDS -e 'BEGIN { server_ips = %w(ip1 ip2 ip3); }; if $_.start_with?("nameserver") ; server_ips.each{|ip| puts "nameserver #{ip}";}; end; puts $_;' resolv.conf
The -i.$SECONDS
flag tells the Ruby interpreter to modify your input file in-place and to save the original version with a filename extension of $SECONDS
, which is the number of seconds your terminal session has been alive. That makes it very unlikely you will permanently clobber a good file with bad code. The backup copies are there if you need them. You just have to clean up afterwards.
EDIT: Here's a short script that inserts rows into an existing file. Note that this does not save multiple copies of the input file like the one-liner does. This script reads an input file (resolv.conf), saves modified output to a temp file, then renames that temp file, replacing the original file. You would run this in the terminal like this $ ./script.rb resolv.conf
Script:
#! /usr/bin/env ruby
require 'tempfile'
require 'fileutils'
server_ips = %w(
ip1
ip2
ip3
)
input_file = ARGV[0]
temp_file = Tempfile.new("#{input_file}.temp")
modified = false
begin
File.open(input_file, 'r') do |file|
file.each_line do |line|
if modified == false && line.start_with?('nameserver')
server_ips.each do |ip|
temp_file.puts "nameserver #{ip}"
end
modified = true
end
temp_file.print line
end
end
temp_file.close
FileUtils.mv(temp_file.path, input_file)
ensure
temp_file.close!
end
See the Ruby documentation for the Tempfile class for an explanation of the begin... ensure... end
usage and the explicit close
on the Tempfile object.
Many thanks Jamin. I have slightly modified your code to suit my future needs as well, like if someone wants to add a block of lines with spaces before a keyword/pattern. This is what I have come up with. May be this helps someone.
txt_to_insert = %q(nameserver 192.168.181.2
nameserver 8.8.8.8)
input_file = "/etc/resolv.conf"
temp_file = Tempfile.new("tmp_file.temp")
modified = false
begin
File.open(input_file, 'r') do |file|
file.each_line do |line|
if modified == false && line.start_with?('nameserver')
temp_file.puts txt_to_insert
modified = true
end
temp_file.print line
end
end
temp_file.close
FileUtils.mv(temp_file.path, input_file)
ensure
temp_file.close!
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.