如何用sed替换指定字符串间的随机文本(兼容空内容场景)
需求与解决方案
问题描述
现有两类文本:
text1"text2" text3"" text4 text5"text6" or text1"text2" text3"randomtext" text4 text5"text6"
需要统一处理为:
text1"text2" text3"foo" text4 text5"text6"
核心需求:仅替换text3后双引号内的内容(无论为空或任意随机文本),不改动其他双引号中的内容。目前仅能处理空引号场景的sed命令:
sed -i 's/text3""//text3"foo"/g' file
尝试的以下命令无效:
sed -i 's/(text3").*(" text4)/\1foo\2/g' file
原因分析
你尝试的命令无效有两个核心原因:
- sed默认使用基础正则表达式(BRE),括号需要转义才能作为捕获组,否则会被当作普通字符匹配;
.*是贪婪匹配规则,会尽可能匹配更多字符,可能跨过后续双引号导致错误替换。
正确的sed命令
方案1:GNU sed(Linux系统常用)
使用扩展正则表达式(加-E或-r参数),用[^"]*匹配双引号内的任意非双引号字符(包括空内容):
sed -i -E 's/(text3")([^"]*)(" text4)/\1foo\3/g' file
如果习惯用基础正则语法,需转义括号:
sed -i 's/\(text3"\)\([^"]*\)\(" text4\)/\1foo\3/g' file
方案2:POSIX兼容sed(适配更多Unix-like系统)
更简洁的写法,直接匹配text3"开头、"结尾的片段,替换为目标内容:
sed -i 's/text3"[^"]*"/text3"foo"/g' file
这里[^"]*会精准匹配双引号内的所有内容(包括空),不会影响其他双引号片段。
效果验证
两类测试文本执行上述命令后,都会得到预期结果:
text1"text2" text3"foo" text4 text5"text6"
内容的提问来源于stack exchange,提问作者diggidre
相关产品推荐
相关产品推荐

