如何使用bash在文件中间添加一行文本?

时间:2011-07-18 20:49:09

标签: linux bash sed awk grep

我正在尝试在bash脚本中的文本文件中间添加一行文本。具体来说,我正在尝试将名称服务器添加到我的/etc/resolv.conf文件中。就目前而言,resolv.conf看起来像这样:

# 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可以做的事情?或者创造性的greping重新创建文件是我最好的举动?

6 个答案:

答案 0 :(得分:40)

以下是使用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开头的第一行替换为包含nameserver 127.0.0.1的新行(您的sed版本可能不支持\n,在这种情况下将n替换为文字换行符)和原始行(由&表示):

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

现在我们只需打印结果:

p

答案 1 :(得分:20)

假设您想在search行之后立即插入,这更简单:

sed -ie '/^search/a nameserver 127.0.0.1' filename
  • -i:就地编辑文件
  • -e:允许在sed表达式
  • 中执行脚本/命令
  • a mynewtext:告诉sed在匹配模式
  • 之后插入文本mynewtext的命令

答案 2 :(得分:8)

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

答案 3 :(得分:2)

如下:

sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf

(类似于:sed: Find pattern over two lines, not replace after that pattern

答案 4 :(得分: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

答案 5 :(得分: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用作标志,表示已找到名称服务器字符串