2015-01-07 74 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 
相關問題