2017-03-03 54 views
1

我正在嘗試爲特定ethX設備向/ etc/network/interfaces添加「dns-nameservers xxxx」行 (這可以更改,也可以另一條線在另一個文件)如何在兩個匹配模式之間但在第二個之前插入一條線

即添加DNS,域名服務器EM1 我想使用類似:

sed -i '/^auto em1/,/^auto/ .....' /etc/network/interfaces 
目前

auto lo 
iface lo inet loopback 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 

我想要什麼:

auto lo 
iface lo inet loopback 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 
dns-nameservers x.x.x.x (<- this line inserted) 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 

在此先感謝。

回答

3

,將覆蓋您當前和未來需求的解決方案是節約每一組給定的設備作爲一個記錄相關聯線,然後從一個函數打印,例如:

$ awk '/^auto/{prtDev()} {dev = dev $0 ORS} END{prtDev()} 
    function prtDev() {printf "%s", dev; dev=""}' file 
auto lo 
iface lo inet loopback 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 

雖然看起來喜歡它只是打印輸入文件原來的樣子,看這是多麼容易然後就調整的功能,有它在第2設備的末尾添加一行:

$ awk '/^auto/{prtDev()} {dev = dev $0 ORS} END{prtDev()} 
    function prtDev() {printf "%s", dev; if (cnt++ == 2) print "dns-nameservers x.x.x.x"; dev=""}' file 
auto lo 
iface lo inet loopback 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 
dns-nameservers x.x.x.x 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 

或只打印的設備記錄「em1」:

$ awk '/^auto/{prtDev()} {dev = dev $0 ORS} END{prtDev()} 
    function prtDev() {if (dev ~/em1 /) printf "%s", dev; dev=""}' file 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 

或匹配特定的網關IP地址或只有環回或您可能想要選擇或操縱的任何其他設備或您希望打印的特定線路或其他任何設備。

+1

非常感謝,最後一個例子是我想要的,我用其他設備替換/ em1 /,它仍然按預期工作。 –

3

awk來救援!

$ awk '/^auto em1/  {f=1} 
     /^auto eth1/ && f {print "NEW LINE GOES HERE"; f=0}1' file 

auto lo 
iface lo inet loopback 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 
NEW LINE GOES HERE 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 

爲了闡明用一個例子的註釋:匹配將繼續跨越文件(和循環如果多於一對開始/結束模式的實測值)。例如

$ awk '/^3/  {f=1} 
     /^6/ && f{print "HERE"; f=0}1' <(seq 5) <(seq 4 7) 

1 
2 
3 
4 
5 
4 
5 
HERE 
6 
7 

第一輸入文件不具有端部圖案(即6)但搜索在所述第二文件繼續。

如果這不是縮進的行爲,請澄清問題。

+0

這將在情況下'END'聲明中受益想要的「自動阻止」將在文件的末尾('END {if(f)pri nt ...}')。 –

+0

應該沒關係,插入點在結束模式之前。 – karakfa

+1

_This可以改變,它可能在另一個文件的另一行._ –

1

這可能爲你工作(GNU SED):

sed '/^auto em1/!b;:a;$bb;n;/^auto/!ba;:b;idns-nameservers x.x.x.x' file 

在遇到此後auto em1打印線,並插入下一行開始auto之前必需的字符串。

+0

非常感謝你,這個例子適用於em1而不是eth4,因爲我相信這是我的例子中的最後一個設備,它不會以auto結束(而是以EOF結束?)。無論如何,感謝任何幫助。 –

+1

@thekamilz請參閱編輯eof條件 – potong

+0

真棒,感謝您的修復! –

1
$ cat program.awk 
/^auto/ && f { print "THE LINE"; f=0 } # auto and f flag up will trigger printing 
/^auto em1/ { f=1 }      # auto em1 raises f flag 
1          # implicit print 
END{ if(f==1) print "THE LINE" }  # if the "auto em1 block" is the last 

修改的測試數據:

$ cat foo 
auto lo 
iface lo inet loopback 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 

測試:

$ awk -f program.awk foo 
auto lo 
iface lo inet loopback 
auto eth1 
iface eth1 inet static 
address 192.168.3.155 
netmask 255.255.255.0 
dns-nameservers 8.8.8.8 
auto em1 
iface em1 inet static 
address 192.168.2.98 
netmask 255.255.255.0 
gateway 192.168.2.1 
THE LINE 

一個行版本:

$ awk '/^auto/ && f { print "THE LINE"; f=0 } /^auto em1/ { f=1 } { print } END{ if(f==1) print "THE LINE" }' foo 
+1

@EdMorton我想說我做了,但根據我的命令歷史,我做錯了。對不起,這似乎工作。 –

相關問題