2011-07-18 40 views
31

我試圖在bash腳本中的文本文件的中間添加一行文本。具體來說,我試圖添加一個名稱服務器到我的/etc/resolv.conf文件。既然這樣,resolv.conf文件看起來是這樣的:如何使用bash將文本行添加到文件的中間?

# Generated by NetworkManager 
domain dhcp.example.com 
search dhcp.example.com 
nameserver 10.0.0.1 
nameserver 10.0.0.2 
nameserver 10.0.0.3 

我的目標是增加nameserver 127.0.0.1所有其他名稱服務器線上方,但低於上述任何文本。最後,我希望我的resolve.conf文件看起來像這樣:

# Generated by NetworkManager 
domain dhcp.example.com 
search dhcp.example.com 
nameserver 127.0.0.1 
nameserver 10.0.0.1 
nameserver 10.0.0.2 
nameserver 10.0.0.3 

這怎麼可能通過bash腳本?這是sed或awk可以做的事情嗎?或者是否會創造性地重新創建文件是我的最佳舉動?

回答

34

下面是使用SED解決方案:

$ sed -n 'H;${x;s/^\n//;s/nameserver .*$/nameserver 127.0.0.1\n&/;p;}' resolv.conf 

# Generated by NetworkManager 
domain dhcp.example.com 
search dhcp.example.com 
nameserver 127.0.0.1 
nameserver 10.0.0.1 
nameserver 10.0.0.2 
nameserver 10.0.0.3 

它是如何工作:第一,抑制與-n標誌sed的輸出。然後,對於每個行,我們追加行保留空間,他們用換行分隔:

H 

當我們來到文件($處理)結束時,我們移動保持空間的內容模式空間:

x 

如果模式空間中的第一行爲空,我們將其替換爲空。

s/^\n// 

然後我們替換含有nameserver 127.0.0.1,新線路的線路開始nameserver第一行(你的sed版本可能不支持\n,在這種情況下,與字面換行符替換n)和原線(由&代表):

s/nameserver .*$/nameserver 127.0.0.1\n&/ 

現在我們只需要打印結果:

p 
+1

這是偉大的。唯一奇怪的是它在新文件的頂部添加了一個空白行。不是什麼大不了的事情,但是它導致了OCD的一刻。 – PHLAK

+4

哦,是的,你是對的!然而,命令'sed -n'H; $ {x; s/^ \ n //; s/nameserver。* \ n/nameserver 127.0.0.1 \ n&/; p;}'resolv.conf'解決了這個問題問題。我在命令中加入了s/^ \ n //',所以它會在模式空間內容的開始處刪除換行符。 – brandizzi

+0

太棒了,謝謝! – PHLAK

8

awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'

+0

偉大的'awk'解決方案,也許是唯一一個不會將整個文件複製到內存... – MestreLion

15

假設你想在search行後立即插入,這是非常簡單的:

sed -ie '/^search/a nameserver 127.0.0.1' filename 
  • -i:到位
  • -e編輯文件:允許腳本執行/命令裏面的sed表達
  • a mynewtext:命令告訴sed插入匹配後的文本mynewtext模式
+0

這就是事情......該搜索行可能會或可能不會在那裏。名稱服務器行應該始終存在,並且我希望在它們之前插入新行,而不管文件的其他內容。 – PHLAK

+0

@PHLAK,Jim提供的解決方案非常好。不過,我會修改它。只需添加一個_special comment_來標記應該輸入新東西的行。例如。像'#<>'這樣的行。然後,而不是'/^search /',您可以查找'/ ^#<> $ /',這使得它不太可能匹配錯誤的行。 – bitmask

+0

你會如何修改這個(如果可能)使用另一個文件中的一行(假設這個文件只有一行),而不是'nameserver 127.0.0.1'? – Juan

0

這可能會爲工作你:

sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf 

或者GNU的sed:

sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf 
0

這裏是一個Perl的解決方案:

perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf

  • -n環圍繞輸入文件的每一行,不自動打印每行

  • -l刪除處理之前換行,並增加了他們之後返回

  • -e執行perl代碼

$f作爲標誌,以表明域名服務器字符串已經發現

相關問題