Linux 如何使用 bash 在文件中间添加一行文本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6739258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I add a line of text to the middle of a file using bash?
提问by PHLAK
I'm trying to add a line of text to the middle of a text file in a bash script. Specifically I'm trying add a nameserver to my /etc/resolv.conf file. As it stands, resolv.conf looks like this:
我正在尝试在 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
My goal is to add nameserver 127.0.0.1
above all other nameserver lines, but below any text above that. In the end I want to my resolve.conf file to look like this:
我的目标是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
How is this possible via a bash script? Is this something sed or awk can do? Or would creative greping to recreate the file be my best move?
这怎么可能通过 bash 脚本实现?这是 sed 或 awk 可以做的吗?或者创造性的greping重新创建文件是我最好的举动吗?
采纳答案by brandizzi
Here is a solution using sed:
这是使用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
How it works: first, suppress the output of sed with the -n
flag. Then, for each line, we append the line to the hold space, separating them with newlines:
工作原理:首先,使用-n
标志抑制 sed 的输出。然后,对于每一行,我们将该行附加到保持空间,用换行符分隔它们:
H
When we come to the end of the file (addressed by $
) we move the content of the hold space to the pattern space:
当我们到达文件末尾(由 寻址$
)时,我们将保持空间的内容移动到模式空间:
x
If the first line in pattern space is blank we replace it with nothing.
如果模式空间中的第一行是空白的,我们将其替换为空。
s/^\n//
Then we replace the first line starting with nameserver
by a line containing nameserver 127.0.0.1
, a new line (Your version of sed
may not support \n
, in which case replace the n
with a literal newline) and the original line (represented by &
):
然后,我们开始替换于第一线nameserver
通过包含线nameserver 127.0.0.1
,新线(你的版本sed
可能不支持\n
,在这种情况下更换n
了面值换行符)与原线(表示为&
):
s/nameserver .*$/nameserver 127.0.0.1\n&/
Now we just need to print the results:
现在我们只需要打印结果:
p
回答by Karoly Horvath
awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'
awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'
回答by sagi
How about something like:
怎么样:
sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf
(similar to this: sed: Find pattern over two lines, not replace after that pattern)
(类似于此:sed:在两行上查找模式,而不是在该模式之后替换)
回答by Jim Garrison
Assuming you want to insert immediately after the search
line, this is much simpler:
假设您想在该search
行之后立即插入,这要简单得多:
sed -ie '/^search/a nameserver 127.0.0.1' filename
-i
: edit file in place-e
: allows the execution of a script/commands inside sed expressiona mynewtext
: command that tells sed to insert the text mynewtext after matched pattern
-i
: 就地编辑文件-e
: 允许在 sed 表达式中执行脚本/命令a mynewtext
: 命令告诉 sed 在匹配模式后插入文本 mynewtext
回答by potong
This might work for you:
这可能对你有用:
sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf
Or GNU sed:
或 GNU sed:
sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf
回答by Chris Koknat
Here's a Perl solution:
这是一个 Perl 解决方案:
perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf
perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf
-n
loop around every line of the input file, do not automatically print every line-l
removes newlines before processing, and adds them back in afterwards-e
execute the perl code
-n
循环输入文件的每一行,不要自动打印每一行-l
在处理之前删除换行符,然后将它们添加回-e
执行perl代码
$f
is used as a flag to indicate that the nameserver string has already been found
$f
用作标志以指示已找到名称服务器字符串