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/\当然,如果第二个字段以literalinstance-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