Linux 在两个模式之间添加字符串-sed

Linux 在两个模式之间添加字符串-sed,linux,bash,sed,Linux,Bash,Sed,我希望构建一个启动脚本,在两个模式之间添加一个文本字符串 8.34.217.13 cds.rhel.updates.googlecloud.com 10.128.0.2 instance-1.c.testenvio1.internal instance-1 **want to add string here** # Added by Google 169.254.169.254 metadata.google.internal # Added by Google 我希望它看起来像这样: 8.

我希望构建一个启动脚本,在两个模式之间添加一个文本字符串

8.34.217.13 cds.rhel.updates.googlecloud.com
10.128.0.2 instance-1.c.testenvio1.internal instance-1 **want to add string here** # Added by Google
169.254.169.254 metadata.google.internal  # Added by Google
我希望它看起来像这样:

8.34.217.13 cds.rhel.updates.googlecloud.com
10.128.0.2 instance-1.c.testenvio1.internal instance-1 104.197.247.254 instance1.com  # Added by Google
169.254.169.254 metadata.google.internal  # Added by Google
我正在使用下面的sed命令,但是当它遇到第一个“instance-1”时,它会插入我的字符串

sed-i的/\/&104.197.247.254 instance1.com/'/etc/hosts
8.34.217.13 cds.rhel.updates.googlecloud.com
10.128.0.2 instance-1104.197.247.254 instance1.com.c.testenvio1.internal instance-1#由Google添加
169.254.169.254 metadata.google.internal#由google添加
试试这个:

sed -i 's/^\([0-9.]* [^ ]* \<instance-1\>\)/\1 104.197.247.254 instance1.com/' /etc/hosts
sed-i的/^\([0-9.]*[^]*\)/\1 104.197.247.254 instance1.com/'/etc/hosts
此表达式将读取前两个字段,然后尝试仅在第三个字段中匹配
instance-1
(这假设字段由单个空格分隔符分隔——如果不是这样,您可以调整正则表达式…)


\(
\)
指示sed应该将匹配的文本存储在变量
\1
中。
^
强制它仅从行首开始匹配。其余的都是非常直接的

也许一些关于数据来源的见解在这里肯定是有帮助的

Google添加的
#
表明这些行包含有关Google计算引擎实例的信息。更重要的是,它们是Google添加的行,幸运的是遵循了预定义的模式

在这种情况下,下面的内容会有所帮助

$ sed -Ei -- 's/([[:blank:]]+instance-1[[:blank:]]+)(#.*)$/\1 104.197.247.254 instance1.com \2/' /etc/hosts
输出

8.34.217.13 cds.rhel.updates.googlecloud.com
10.128.0.2-instance-1-c.testenvio1.internal instance-1   104.197.247.254 instance1.com # Added by Google
169.254.169.254 metadata.google.internal  # Added by Google


旁注:实际的空格数也会保留。

在实例-1后面加上空格,以区别于第一次出现的空格:

$ sed -i 's/instance-1 /&104.197.247.254 instance1.com /g' inputFile

如果您知道它总是第二次出现,请使用,
/2
替换它

$ sed -i 's/instance-1/& 104.197.247.254 instance1.com /2' inputFile
如果您想在两个模式之间添加字符串,以供将来参考

$ sed '/pattern1/,/pattern2/s//& INSERT THIS TEXT/g' inputFile
对于这个例子,它看起来像

# You still need that whitespace to distinguish the second occurrence from first:
$ sed '/instance-1 /,/# Added/s//&104.197.247.254 instance1.com /g' inputFile

在模式中包含instance1后面的空格。是否简单:sed-i's/\/&104.197.247.254 instance1.com/'/etc/hosts。这没有造成任何更改您的
\>
匹配单词的结尾,如果在模式中包含空格,则不会发生这种情况。您需要
sed-i/\当然,如果第二个字段以literal
instance-1
结尾,则该字段将不起作用,因为它仍将替换该字段instance@HardcoreHenry好消息<代码>\
将匹配任何类似于
\u实例-1\u
实例-1的内容。也许op应该选择
/([:blank:]+instance-1[[:blank:]+)(#.*)$/\1 104.197.247.254 instance1.com\2/
或者启用
sed
-E
选项。这将匹配
some-stuff-follower-byinstance1(空格)之类的内容
并使用
-i
执行就地编辑可能会导致不需要的更改。tern匹配基于输入
模式
。如果
模式改变,那么结果也会改变。在任何情况下,只要假设是真的,就可以安全地使用第二个选项。重新启动后,/etc/hosts将使用默认配置进行更新谷歌添加的内容保持一致。表达式可以工作,但不会将更改提交给/etc/hosts。我尝试将-E更改为-I(就地编辑),但遇到了以下错误:“sed:-E expression#1,char 81:s命令的RHS上的无效引用\2”@glux您应该将这两个参数都设置为
-Ei
E
启用扩展正则表达式,而
I
执行就地编辑。由于
i
查找备份前缀的参数,因此需要将其放在最后。。您甚至可以添加一个
--
来标记参数的结尾。请参阅编辑
# You still need that whitespace to distinguish the second occurrence from first:
$ sed '/instance-1 /,/# Added/s//&104.197.247.254 instance1.com /g' inputFile