如何用Shell脚本替换文件中特定单词间内容且不改动其余部分
解决sed贪婪匹配导致的过度替换问题
你的问题出在sed的贪婪匹配特性上:.*会匹配从named开始到行内最后一个apples的所有内容,所以才会把后面的句子也错误替换。
解决方案
方法1:使用GNU sed的非贪婪匹配(推荐)
GNU sed支持非贪婪匹配语法.*?,配合-E启用扩展正则表达式,就能匹配到第一个apples就停止:
file="input.txt" new_text1="Conor has 10" sed -i -E "s/named.*?apples/named $new_text1 apples/g" "$file"
方法2:兼容BSD sed(如macOS系统)
如果是BSD sed(不支持.*?),可以用字符集限定的方式匹配到第一个apples:
file="input.txt" new_text1="Conor has 10" sed -i "" -E "s/named([^a]*a[^p]*p[^p]*l[^e]*e[^s]*s)apples/named $new_text1 apples/g" "$file"
或者如果第一个apples后有明确的分隔符(比如你的例子里是句号),可以更简单:
sed -i "" "s/named[^.]*apples/named $new_text1 apples/g" "$file"
效果验证
执行后目标文件内容会变为:
Student named Conor has 10 apples. Docter says, apples are good for health.
内容的提问来源于stack exchange,提问作者Discovery
相关产品推荐
相关产品推荐

