2017-03-03 34 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我想说我做了,但根据我的命令历史,我做错了。对不起,这似乎工作。 –

相关问题