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

PHL*_*LAK 41 linux bash awk grep sed

我正在尝试在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
Run Code Online (Sandbox Code Playgroud)

我的目标是添加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
Run Code Online (Sandbox Code Playgroud)

这怎么可能通过bash脚本?这是sed还是awk可以做的事情?或者创造性的greping重新创建文件是我最好的举动?

bra*_*zzi 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
Run Code Online (Sandbox Code Playgroud)

工作原理:首先,用-n标志来抑制sed的输出.然后,对于每一行,我们将该行附加到保留空间,用换行符分隔它们:

H
Run Code Online (Sandbox Code Playgroud)

当我们到文件的末尾(寻址$)时,我们将保留空间的内容移动到模式空间:

x
Run Code Online (Sandbox Code Playgroud)

如果模式空间中的第一行是空白,我们将其替换为空.

s/^\n//
Run Code Online (Sandbox Code Playgroud)

然后我们将第一行替换为nameserver包含一行nameserver 127.0.0.1的新行(您的版本sed可能不支持\n,在这种情况下替换n为文字换行符)和原始行(由...表示&):

s/nameserver .*$/nameserver 127.0.0.1\n&/
Run Code Online (Sandbox Code Playgroud)

现在我们只需打印结果:

p
Run Code Online (Sandbox Code Playgroud)

  • 哦,是的,你是对的!然而,命令`sed -n'H; $ {x; s/^ \n //; s/nameserver.*\n/nameserver 127.0.0.1 \n&/; p;}'resolv.conf`解决了这个问题问题.我在命令中添加了`s/^ \n //`,因此它将删除模式空间内容开头的换行符. (4认同)
  • 可能是因为行尾没有换行符.它也很容易解决:`sed -n'H; $ {x; s/^ \n //; s/nameserver.*$/nameserver 127.0.0.1 \n&/; p;}'resolv.conf`现在我们从第一个名称服务器替换到文件结尾 - 我用`/`行结尾的标记替换`/ nameserver.*\n /`中的`\n`.同样,不是`/ nameserver 127.0.0.1 \n&/`中的`\n`可能必须用`\`替换,后跟一些sed版本中的实际换行符. (3认同)

Jim*_*son 21

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

sed -ie '/^search/a nameserver 127.0.0.1' filename
Run Code Online (Sandbox Code Playgroud)
  • -i :编辑文件到位
  • -e :允许在sed表达式中执行脚本/命令
  • a mynewtext :命令告诉sed在匹配模式后插入文本mynewtext


Kar*_*ath 8

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