Bash:在特定位置的文件中插入一行

dgi*_*bbs 40 linux bash

我正在编写一个脚本,要求我在配置文件的特定部分添加行.例如

之前:

ServerActors=IpServer.UdpServerUplink MasterServerAddress=unreal.epicgames.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master0.gamespy.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.mplayer.com MasterServerPort=27900
ServerActors=UWeb.WebServer
Run Code Online (Sandbox Code Playgroud)

后:

ServerActors=IpServer.UdpServerUplink MasterServerAddress=unreal.epicgames.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master0.gamespy.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.mplayer.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.qtracker.com MasterServerPort=27900
ServerActors=UWeb.WebServer
Run Code Online (Sandbox Code Playgroud)

如您所见,添加了一个新行.我的bash脚本如何插入该行?我猜我需要使用sed.

Adr*_*rth 85

如果要在特定字符串匹配后添加一行:

$ awk '/master.mplayer.com/ { print; print "new line"; next }1' foo.input
ServerActors=IpServer.UdpServerUplink MasterServerAddress=unreal.epicgames.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master0.gamespy.com MasterServerPort=27900
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.mplayer.com MasterServerPort=27900
new line
ServerActors=UWeb.WebServer
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么这不会得到更多的投票,这是处理解决方案的一种更动态的方式,而不是明确知道您的搜索文本所在的行号.来自我的+1 (4认同)
  • @AndyRay因为shell重定向在任何命令运行之前发生,这意味着文件会立即被截断.另见[本回答](http://askubuntu.com/a/8418).解决这个问题的唯一方法是使用临时文件,例如`sed -i`可以透明地执行.还有来自`moreutils`的`sponge`解决了这个问题. (3认同)
  • 它显示了预期的输出,但如何将该输出添加到文件中?文件不变 (3认同)
  • 为什么不将其通过管道传输回同一文件?`awk ... foo.input> foo.input`只清空该文件 (2认同)

小智 27

你可以使用这样的东西:

请注意,必须在多行上输入命令,因为sed不允许使用"\n"编辑换行符或者像某些工具一样使用Ctrl-V/Ctrl-M组合键编码.反斜杠说"忽略我击中返回键,我还没完成我的命令".

sed -i.bak '4i\
This is the new line\
' filename
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题(它将在第3行和第4行之间插入).

如果你想把这个命令本身放到一个shell脚本中,你必须转义反斜杠,这样它们就不会被bash吃掉并且无法传递给sed.在脚本内部,命令变为:

sed -i.bak '4i\\
This is the new line\\
' filename
Run Code Online (Sandbox Code Playgroud)

  • 我明白了,你正在指定行号 (2认同)
  • 什么是.bak代表什么? (2认同)

Ken*_*ent 13

awk 'NR==5{print "new line text"}7' file
Run Code Online (Sandbox Code Playgroud)

  • 如果其他人感到困惑,这个例子中的`7`可以是任何评估为true的值.这使得Awk知道要打印每一行.如果那里没有值,则只有匹配的行(在这种情况下为#5)将生成输出(在这种情况下为"新行文本"). (6认同)
  • 抱歉,这里的"7"是什么?(`..."} 7`) (3认同)
  • @setevoy 它将应用 awk 的默认操作:打印。 (2认同)

rub*_*o77 5

您可以在某个字符串匹配后将其添加到sed文件中:filenamepattern

sed '/pattern/a some text here' filename
Run Code Online (Sandbox Code Playgroud)

在你的例子中

sed '/master.mplayer.com/a \  new line' filename
Run Code Online (Sandbox Code Playgroud)

(反斜杠掩盖了新行中的第一个空格,因此您可以在开头添加更多空格)

来源:https ://unix.stackexchange.com/a/121166/20661