2015-01-07 71 views
1

我知道如何将字符串(或文本)添加到文件的结尾以及文件的开头,但无法谷歌插入字符串的方式(使用变量)在模式之后/之前。Ruby:在一个模式之后/之前插入一个字符串

例如,

[email protected]:~# cat /etc/resolv.conf 
search reachvikas.com 
nameserver 192.168.1.27 
[email protected]:~# 

现在,我想补充另一个域名服务器像下面。

[email protected]:~# cat /etc/resolv.conf 
search reachvikas.com 
nameserver 192.168.181.2 
nameserver 192.168.1.27 
[email protected]:~# 

我可以很容易地做到这一点,但只是看着Ruby的出路。

更新:我写了下面的代码,但是这代替了最后一行并没有增加一个。我想调整file.seek会帮助我,但不知道如何。

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 

回答

1

这是一个Ruby“单线程”,它可以完成我认为你正在尝试做的事情。我创建了一个与您的第一个文件内容匹配的resolv.conf文件。然后,下面的Ruby“单线程”为了便于阅读而分成几行,搜索以“nameserver”开头的行,并用您定义的IP插入任意新的namservers列表。

$ 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 

如果你真的想把它当作一个班轮,你必须添加在需要断行分号:

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 

-i.$SECONDS标志告诉Ruby解释器来修改你的输入文件IN-放置并保存原始版本的文件扩展名为$SECONDS,这是终端会话存活的秒数。这使得你不可能永久地破坏代码不好的好文件。如果您需要它们,备份副本就在那里。之后你必须清理干净。

编辑:这是一个简短的脚本,插入到现有的文件行。请注意,这不会像单线程那样保存输入文件的多个副本。该脚本读取输入文件(resolv.conf),将修改的输出保存到临时文件,然后重命名该临时文件,替换原始文件。你会在终端这样$ ./script.rb resolv.conf

脚本运行此:

#! /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 

请参阅Tempfile类的Ruby文档的begin... ensure... end使用的说明和将它视为对象上明确close

+0

谢谢Jamin,当我在bash shell中使用它时,此代码工作正常,但不在ruby脚本中。我如何重新格式化这段代码以在ruby脚本中使用。原谅我对此的无知,我是一个红宝石新手。另外,我也写了一个代码,它可以帮助我。请在原始问题 – vikas027

+0

中查看我的更新嗨,Vikas。看到我上面的编辑。关于你使用'r +'模式修改文件的附加代码,我老实说从来没有这样做过。也许这是习惯,但我总是创建具有修改内容的临时文件,然后重命名它们以替换现有文件。 –

+0

我在下面看到你的编辑(只能在这里留言)。它可以工作,但是你可以在第一行使用'%q'而不是'%qw'来清理它。 '%qw'给出了一组引用的单词。如果你只想插入一个静态的文本块,你可以使用'%q'(单引号运算符),然后删除'txt_to_insert.each do | ip | ... end'循环,而是用'temp_file.puts txt_to_insert'将整个文本块打印到文件中。请记住,'%q()'在括号内保留换行符,所以你应该以'%q(nameserver 192.168.181.2',然后换行符开头) –

0

非常感谢Jamin。我稍微修改了你的代码以适应我未来的需求,就像有人想在关键字/模式之前添加一行带空格的行一样。这是我想出的。可能会帮助某人。

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 
相关问题