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中添加一个nameserverconf文件。目前,决心。设计是这样的:
# 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添加到所有其他nameserver行之上,但是在上面的任何文本下面。最后,我要下定决心。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能做的吗?或者,重新创建文件是我的最佳选择?
6 个解决方案
#1
35
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
#2
16
Assuming you want to insert immediately after the search
line, this is much simpler:
假设您想要在搜索行之后立即插入,这要简单得多:
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 expression - -e:允许在sed表达式中执行脚本/命令
-
a mynewtext
: command that tells sed to insert the text mynewtext after matched pattern - 一个mynewtext:命令,告诉sed在匹配模式之后插入文本mynewtext
#3
8
awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'
awk ' / ^命名服务器/ & & ! modif { printf("插入\ n ");modif = 1 } {打印} '
#4
2
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:在两行中查找模式,而不是在该模式之后替换)
#5
0
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
#6
0
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而言,“如果(不是$ f和/ ^命名服务器/){打印“命名服务器127.0.0.1”;$ f = 1 };打印“resolv.conf
-
-n
loop around every line of the input file, do not automatically print every line-n循环每一行输入文件,不要自动打印每一行
-
-l
removes newlines before processing, and adds them back in afterwards-l在处理之前删除新行,之后再添加
-
-e
execute the perl code-e执行perl代码
$f
is used as a flag to indicate that the nameserver string has already been found
$f被用作一个标志,表示已找到nameserver字符串
#1
35
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
#2
16
Assuming you want to insert immediately after the search
line, this is much simpler:
假设您想要在搜索行之后立即插入,这要简单得多:
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 expression - -e:允许在sed表达式中执行脚本/命令
-
a mynewtext
: command that tells sed to insert the text mynewtext after matched pattern - 一个mynewtext:命令,告诉sed在匹配模式之后插入文本mynewtext
#3
8
awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'
awk ' / ^命名服务器/ & & ! modif { printf("插入\ n ");modif = 1 } {打印} '
#4
2
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:在两行中查找模式,而不是在该模式之后替换)
#5
0
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
#6
0
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而言,“如果(不是$ f和/ ^命名服务器/){打印“命名服务器127.0.0.1”;$ f = 1 };打印“resolv.conf
-
-n
loop around every line of the input file, do not automatically print every line-n循环每一行输入文件,不要自动打印每一行
-
-l
removes newlines before processing, and adds them back in afterwards-l在处理之前删除新行,之后再添加
-
-e
execute the perl code-e执行perl代码
$f
is used as a flag to indicate that the nameserver string has already been found
$f被用作一个标志,表示已找到nameserver字符串