Unix环境下替换文件中test开头行第二个冒号后的子串
修正你的sed命令,实现目标替换
问题出在你写的正则表达式逻辑上,我们来一步步解决:
正确的sed命令
针对单行测试,你可以用这个命令:
echo 'test:abc.io/gng-cp:1.34.2-of1231' | sed 's/^\(test:[^:]*:\).*/\11.333.555/'
执行后就能得到你想要的结果:
test:abc.io/gng-cp:1.333.555
如果要直接修改abc.txt文件,加上-i选项(注意:macOS环境下的sed需要写成-i ''):
sed -i 's/^\(test:[^:]*:\).*/\11.333.555/' abc.txt
为什么你的原命令不对?
你原来的正则\([^test:]*:\)是个否定字符集,它的意思是"匹配任意一个不是t、e、s、:的字符"——这完全不是你想要的逻辑!
在你的测试字符串test:abc.io/gng-cp:1.34.2-of1231里,这个否定字符集匹配不到任何内容(因为开头就是t,属于被排除的字符),所以捕获组\1是空的。然后:.*匹配了从第一个冒号到结尾的所有内容,替换后就只剩下test:加上新的版本号,自然丢失了中间的abc.io/gng-cp部分。
正确正则的逻辑拆解
^:锚定行开头,确保只处理以test开头的行,避免误改其他包含test的行\(test:[^:]*:\):捕获我们需要保留的部分:test::匹配行开头的固定前缀[^:]*:匹配任意数量的非冒号字符(也就是第二个冒号之前的内容)::匹配第二个冒号
.*:匹配第二个冒号之后的所有内容,我们要把这部分替换掉\11.333.555:用捕获到的保留部分\1,加上你指定的新值,完成替换
内容的提问来源于stack exchange,提问作者gorants
相关产品推荐
相关产品推荐

